Compare commits

...

4 Commits

Author SHA1 Message Date
Florian Rival
d5f73bea0d Address some review comment 2022-10-04 22:46:55 +02:00
Florian Rival
32c69ab78a Fix typing 2022-10-04 22:46:55 +02:00
Florian Rival
3dd5e2c242 Refactor to have resourceManagementProps everywhere 2022-10-04 22:46:55 +02:00
Florian Rival
fbfcd3da5d [WIP] Allow to choose resources from the asset store in the desktop app 2022-10-04 22:42:15 +02:00
64 changed files with 920 additions and 1030 deletions

View File

@@ -16,7 +16,7 @@ import EventsFunctionsExtensionsContext from '../EventsFunctionsExtensionsLoader
import { showErrorBox } from '../UI/Messages/MessageBox';
import LinearProgress from '../UI/LinearProgress';
import { AssetStoreContext } from './AssetStoreContext';
import { type OnFetchNewlyAddedResourcesFunction } from '../ProjectsStorage/ResourceFetcher';
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
type Props = {|
assetPack: AssetPack,
@@ -27,7 +27,7 @@ type Props = {|
project: gdProject,
objectsContainer: gdObjectsContainer,
onObjectAddedFromAsset: (object: gdObject) => void,
onFetchNewlyAddedResources: OnFetchNewlyAddedResourcesFunction,
resourceManagementProps: ResourceManagementProps,
|};
export const AssetPackDialog = ({
@@ -39,7 +39,7 @@ export const AssetPackDialog = ({
project,
objectsContainer,
onObjectAddedFromAsset,
onFetchNewlyAddedResources,
resourceManagementProps,
}: Props) => {
const missingAssetShortHeaders = assetShortHeaders.filter(
assetShortHeader => !addedAssetIds.includes(assetShortHeader.id)
@@ -82,7 +82,7 @@ export const AssetPackDialog = ({
});
});
await onFetchNewlyAddedResources();
await resourceManagementProps.onFetchNewlyAddedResources();
setAreAssetsBeingInstalled(false);
onAssetsAdded();
@@ -104,7 +104,7 @@ export const AssetPackDialog = ({
onObjectAddedFromAsset,
onAssetsAdded,
environment,
onFetchNewlyAddedResources,
resourceManagementProps,
]
);

View File

@@ -15,12 +15,7 @@ import HelpButton from '../UI/HelpButton';
import { Column, Line } from '../UI/Grid';
import { Tabs, Tab } from '../UI/Tabs';
import { AssetStore } from '.';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../ResourcesList/ResourceSource';
import { type OnFetchNewlyAddedResourcesFunction } from '../ProjectsStorage/ResourceFetcher';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
import {
sendAssetAddedToProject,
sendNewObjectCreated,
@@ -71,10 +66,7 @@ type Props = {|
project: gdProject,
layout: ?gdLayout,
objectsContainer: gdObjectsContainer,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
onFetchNewlyAddedResources: OnFetchNewlyAddedResourcesFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
onClose: () => void,
onCreateNewObject: (type: string) => void,
onObjectAddedFromAsset: gdObject => void,
@@ -84,10 +76,7 @@ export default function NewObjectDialog({
project,
layout,
objectsContainer,
resourceSources,
onChooseResource,
onFetchNewlyAddedResources,
resourceExternalEditors,
resourceManagementProps,
onClose,
onCreateNewObject,
onObjectAddedFromAsset,
@@ -180,7 +169,7 @@ export default function NewObjectDialog({
onObjectAddedFromAsset(object);
});
await onFetchNewlyAddedResources();
await resourceManagementProps.onFetchNewlyAddedResources();
} catch (error) {
console.error('Error while installing the asset:', error);
showErrorBox({
@@ -202,7 +191,7 @@ export default function NewObjectDialog({
onObjectAddedFromAsset,
openedAssetShortHeader,
environment,
onFetchNewlyAddedResources,
resourceManagementProps,
]
);
@@ -342,7 +331,7 @@ export default function NewObjectDialog({
project={project}
objectsContainer={objectsContainer}
onObjectAddedFromAsset={onObjectAddedFromAsset}
onFetchNewlyAddedResources={onFetchNewlyAddedResources}
resourceManagementProps={resourceManagementProps}
/>
)}
</>

View File

@@ -1,9 +1,5 @@
// @flow
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../../ResourcesList/ResourceSource';
/**
* The props given to any behavior editor
@@ -12,7 +8,5 @@ export type BehaviorEditorProps = {|
behavior: gdBehavior,
project: gdProject,
object: gdObject,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
|};

View File

@@ -292,9 +292,7 @@ const Physics2Editor = (props: Props) => {
</Trans>
}
project={props.project}
resourceSources={props.resourceSources}
onChooseResource={props.onChooseResource}
resourceExternalEditors={props.resourceExternalEditors}
resourceManagementProps={props.resourceManagementProps}
resourcesLoader={resourcesLoader}
resourceKind={'image'}
initialResourceName={''}

View File

@@ -14,11 +14,7 @@ import BehaviorsEditorService from './BehaviorsEditorService';
import Window from '../Utils/Window';
import { Column, Line } from '../UI/Grid';
import RaisedButton from '../UI/RaisedButton';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
import DismissableTutorialMessage from '../Hints/DismissableTutorialMessage';
import { ColumnStackLayout } from '../UI/Layout';
import useForceUpdate from '../Utils/UseForceUpdate';
@@ -41,9 +37,7 @@ type Props = {|
object: gdObject,
onUpdateBehaviorsSharedData: () => void,
onSizeUpdated?: ?() => void,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
|};
const BehaviorsEditor = (props: Props) => {
@@ -256,10 +250,8 @@ const BehaviorsEditor = (props: Props) => {
behavior={behavior}
project={project}
object={object}
resourceSources={props.resourceSources}
onChooseResource={props.onChooseResource}
resourceExternalEditors={
props.resourceExternalEditors
resourceManagementProps={
props.resourceManagementProps
}
/>
</Line>

View File

@@ -26,11 +26,7 @@ import {
type EnumeratedEffectMetadata,
setEffectDefaultParameters,
} from './EnumerateEffects';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
import ScrollView from '../UI/ScrollView';
import { EmptyPlaceholder } from '../UI/EmptyPlaceholder';
import {
@@ -59,9 +55,7 @@ const styles = {
type Props = {|
project: gdProject,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
effectsContainer: gdEffectsContainer,
onEffectsUpdated: () => void,
target: 'object' | 'layer',
@@ -367,14 +361,8 @@ export default function EffectsList(props: Props) {
effectMetadata.parametersSchema
}
project={props.project}
resourceSources={
props.resourceSources
}
onChooseResource={
props.onChooseResource
}
resourceExternalEditors={
props.resourceExternalEditors
resourceManagementProps={
props.resourceManagementProps
}
renderExtraDescriptionText={
showEffectParameterNames

View File

@@ -12,13 +12,11 @@ import type { ObjectWithContext } from '../ObjectsList/EnumerateObjects';
import Window from '../Utils/Window';
import ObjectEditorDialog from '../ObjectEditor/ObjectEditorDialog';
import { type ObjectEditorTab } from '../ObjectEditor/ObjectEditorDialog';
import { type OnFetchNewlyAddedResourcesFunction } from '../ProjectsStorage/ResourceFetcher';
const gd: libGDevelop = global.gd;
type Props = {|
project: gdProject,
onFetchNewlyAddedResources: OnFetchNewlyAddedResourcesFunction,
globalObjectsContainer: gdObjectsContainer,
eventsFunctionsExtension: gdEventsFunctionsExtension,
eventsBasedObject: gdEventsBasedObject,
@@ -212,9 +210,12 @@ export default class EventBasedObjectChildrenEditor extends React.Component<
objectsContainer={eventsBasedObject}
layout={null}
// TODO EBO Allow to use project resources as place holders
resourceSources={[]}
resourceExternalEditors={[]}
onChooseResource={() => Promise.resolve([])}
resourceManagementProps={{
resourceSources: [],
resourceExternalEditors: [],
onChooseResource: async () => [],
onFetchNewlyAddedResources: async () => {},
}}
selectedObjectNames={this.state.selectedObjectNames}
onEditObject={this.editObject}
onDeleteObject={this._onDeleteObject(i18n)}
@@ -243,9 +244,6 @@ export default class EventBasedObjectChildrenEditor extends React.Component<
launchProjectDataOnlyPreview: () => {},
launchProjectWithLoadingScreenPreview: () => {},
}}
onFetchNewlyAddedResources={
this.props.onFetchNewlyAddedResources
}
/>
</Line>
{this.state.editedObjectWithContext && (
@@ -254,9 +252,12 @@ export default class EventBasedObjectChildrenEditor extends React.Component<
object={this.state.editedObjectWithContext.object}
initialTab={this.state.editedObjectInitialTab}
project={project}
resourceSources={[]}
resourceExternalEditors={[]}
onChooseResource={() => Promise.resolve([])}
resourceManagementProps={{
resourceSources: [],
resourceExternalEditors: [],
onChooseResource: async () => [],
onFetchNewlyAddedResources: async () => {},
}}
onComputeAllVariableNames={() => {
return [];
// TODO EBO Find undeclared variables in the parent events.

View File

@@ -4,12 +4,10 @@ import * as React from 'react';
import Dialog, { DialogPrimaryButton } from '../UI/Dialog';
import EventsBasedObjectEditor from './index';
import HelpButton from '../UI/HelpButton';
import { type OnFetchNewlyAddedResourcesFunction } from '../ProjectsStorage/ResourceFetcher';
type Props = {|
onApply: () => void,
project: gdProject,
onFetchNewlyAddedResources: OnFetchNewlyAddedResourcesFunction,
globalObjectsContainer: gdObjectsContainer,
eventsFunctionsExtension: gdEventsFunctionsExtension,
eventsBasedObject: gdEventsBasedObject,
@@ -55,7 +53,6 @@ export default class EventsBasedObjectEditorDialog extends React.Component<
>
<EventsBasedObjectEditor
project={project}
onFetchNewlyAddedResources={this.props.onFetchNewlyAddedResources}
globalObjectsContainer={globalObjectsContainer}
eventsFunctionsExtension={eventsFunctionsExtension}
eventsBasedObject={eventsBasedObject}

View File

@@ -12,16 +12,13 @@ import EventsBasedObjectPropertiesEditor from './EventsBasedObjectPropertiesEdit
import EventBasedObjectChildrenEditor from './EventBasedObjectChildrenEditor';
import { ColumnStackLayout } from '../UI/Layout';
import { Line } from '../UI/Grid';
import { type OnFetchNewlyAddedResourcesFunction } from '../ProjectsStorage/ResourceFetcher';
import { showWarningBox } from '../UI/Messages/MessageBox';
const gd: libGDevelop = global.gd;
type TabName = 'configuration' | 'properties' | 'children';
type Props = {|
project: gdProject,
onFetchNewlyAddedResources: OnFetchNewlyAddedResourcesFunction,
globalObjectsContainer: gdObjectsContainer,
eventsFunctionsExtension: gdEventsFunctionsExtension,
eventsBasedObject: gdEventsBasedObject,
@@ -164,7 +161,6 @@ export default class EventsBasedObjectEditor extends React.Component<
{currentTab === 'children' && (
<EventBasedObjectChildrenEditor
project={project}
onFetchNewlyAddedResources={this.props.onFetchNewlyAddedResources}
globalObjectsContainer={globalObjectsContainer}
eventsFunctionsExtension={eventsFunctionsExtension}
eventsBasedObject={eventsBasedObject}

View File

@@ -19,11 +19,7 @@ import OptionsEditorDialog from './OptionsEditorDialog';
import { showWarningBox } from '../UI/Messages/MessageBox';
import EventsBasedBehaviorEditorDialog from '../EventsBasedBehaviorEditor/EventsBasedBehaviorEditorDialog';
import EventsBasedObjectEditorDialog from '../EventsBasedObjectEditor/EventsBasedObjectEditorDialog';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
import BehaviorMethodSelectorDialog from './BehaviorMethodSelectorDialog';
import ObjectMethodSelectorDialog from './ObjectMethodSelectorDialog';
import ExtensionFunctionSelectorDialog from './ExtensionFunctionSelectorDialog';
@@ -47,7 +43,6 @@ import PreferencesContext from '../MainFrame/Preferences/PreferencesContext';
import { ParametersIndexOffsets } from '../EventsFunctionsExtensionsLoader';
import { sendEventsExtractedAsFunction } from '../Utils/Analytics/EventSender';
import Window from '../Utils/Window';
import { type OnFetchNewlyAddedResourcesFunction } from '../ProjectsStorage/ResourceFetcher';
const gd: libGDevelop = global.gd;
const isDev = Window.isDev();
@@ -56,10 +51,7 @@ type Props = {|
project: gdProject,
eventsFunctionsExtension: gdEventsFunctionsExtension,
setToolbar: (?React.Node) => void,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
onFetchNewlyAddedResources: OnFetchNewlyAddedResourcesFunction,
resourceManagementProps: ResourceManagementProps,
openInstructionOrExpression: (
extension: gdPlatformExtension,
type: string
@@ -1095,9 +1087,7 @@ export default class EventsFunctionsExtensionEditor extends React.Component<
events={selectedEventsFunction.getEvents()}
onOpenExternalEvents={() => {}}
onOpenLayout={() => {}}
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceExternalEditors={this.props.resourceExternalEditors}
resourceManagementProps={this.props.resourceManagementProps}
openInstructionOrExpression={
this.props.openInstructionOrExpression
}
@@ -1488,7 +1478,6 @@ export default class EventsFunctionsExtensionEditor extends React.Component<
{editedEventsBasedObject && this._globalObjectsContainer && (
<EventsBasedObjectEditorDialog
project={project}
onFetchNewlyAddedResources={this.props.onFetchNewlyAddedResources}
globalObjectsContainer={this._globalObjectsContainer}
eventsFunctionsExtension={eventsFunctionsExtension}
eventsBasedObject={editedEventsBasedObject}

View File

@@ -2,11 +2,7 @@
import * as React from 'react';
import InlinePopover from './InlinePopover';
import ParameterRenderingService from './ParameterRenderingService';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
import { type EventsScope } from '../InstructionOrExpression/EventsScope.flow';
import { setupInstructionParameters } from '../InstructionOrExpression/SetupInstructionParameters';
import { getObjectParameterIndex } from '../InstructionOrExpression/EnumerateInstructions';
@@ -29,9 +25,7 @@ type Props = {|
anchorEl: ?any,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
|};
type State = {|
@@ -164,9 +158,7 @@ export default class InlineParameterEditor extends React.Component<
ref={field => (this._field = field)}
parameterRenderingService={ParameterRenderingService}
isInline
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceExternalEditors={this.props.resourceExternalEditors}
resourceManagementProps={this.props.resourceManagementProps}
/>
</InlinePopover>
);

View File

@@ -5,11 +5,7 @@ import * as React from 'react';
import Dialog, { DialogPrimaryButton } from '../../UI/Dialog';
import FlatButton from '../../UI/FlatButton';
import InstructionEditor from '.';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../../ResourcesList/ResourceSource';
import { type EventsScope } from '../../InstructionOrExpression/EventsScope.flow';
type Props = {|
@@ -19,9 +15,7 @@ type Props = {|
objectsContainer: gdObjectsContainer,
instruction: gdInstruction,
isCondition: boolean,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
style?: Object,
isNewInstruction: boolean,
onCancel: () => void,

View File

@@ -10,11 +10,7 @@ import { mapFor } from '../../Utils/MapFor';
import EmptyMessage from '../../UI/EmptyMessage';
import ParameterRenderingService from '../ParameterRenderingService';
import HelpButton from '../../UI/HelpButton';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../../ResourcesList/ResourceSource';
import { Column, Line, Spacer } from '../../UI/Grid';
import AlertMessage from '../../UI/AlertMessage';
import DismissableAlertMessage from '../../UI/DismissableAlertMessage';
@@ -74,9 +70,7 @@ type Props = {|
instruction: gdInstruction,
isCondition: boolean,
focusOnMount?: boolean,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
style?: Object,
openInstructionOrExpression: (
extension: gdPlatformExtension,
@@ -116,9 +110,7 @@ const InstructionParametersEditor = React.forwardRef<
focusOnMount,
style,
openInstructionOrExpression,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
},
ref
) => {
@@ -373,9 +365,7 @@ const InstructionParametersEditor = React.forwardRef<
objectsContainer={objectsContainer}
key={i}
parameterRenderingService={ParameterRenderingService}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
ref={field => {
if (isFirstVisibleParameterField) {
firstVisibleField.current = field;

View File

@@ -4,11 +4,7 @@ import { Trans } from '@lingui/macro';
import * as React from 'react';
import Dialog, { DialogPrimaryButton } from '../../UI/Dialog';
import FlatButton from '../../UI/FlatButton';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../../ResourcesList/ResourceSource';
import InstructionParametersEditor, {
type InstructionParametersEditorInterface,
} from './InstructionParametersEditor';
@@ -57,9 +53,7 @@ type Props = {|
objectsContainer: gdObjectsContainer,
instruction: gdInstruction,
isCondition: boolean,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
style?: Object,
isNewInstruction: boolean,
onCancel: () => void,
@@ -102,9 +96,7 @@ export default function NewInstructionEditorDialog({
isNewInstruction,
scope,
onSubmit,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
openInstructionOrExpression,
}: Props) {
const forceUpdate = useForceUpdate();
@@ -262,9 +254,7 @@ export default function NewInstructionEditorDialog({
objectName={chosenObjectName}
isCondition={isCondition}
instruction={instruction}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
openInstructionOrExpression={openInstructionOrExpression}
ref={instructionParametersEditor}
focusOnMount={!!instructionType}

View File

@@ -2,11 +2,7 @@
import { Trans } from '@lingui/macro';
import Popover from '@material-ui/core/Popover';
import * as React from 'react';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../../ResourcesList/ResourceSource';
import {
useNewInstructionEditor,
getInstructionMetadata,
@@ -42,9 +38,7 @@ type Props = {|
objectsContainer: gdObjectsContainer,
instruction: gdInstruction,
isCondition: boolean,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
style?: Object,
anchorEl: ?HTMLElement,
isNewInstruction: boolean,

View File

@@ -5,11 +5,7 @@ import InstructionSelector from './InstructionOrExpressionSelector/InstructionSe
import InstructionParametersEditor, {
type InstructionParametersEditorInterface,
} from './InstructionParametersEditor';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../../ResourcesList/ResourceSource';
import { type EventsScope } from '../../InstructionOrExpression/EventsScope.flow';
const styles = {
@@ -31,9 +27,7 @@ type Props = {|
objectsContainer: gdObjectsContainer,
instruction: gdInstruction,
isCondition: boolean,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
style?: Object,
openInstructionOrExpression: (
extension: gdPlatformExtension,
@@ -83,9 +77,7 @@ export default class InstructionEditor extends React.Component<Props, State> {
objectsContainer={objectsContainer}
isCondition={isCondition}
instruction={instruction}
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceExternalEditors={this.props.resourceExternalEditors}
resourceManagementProps={this.props.resourceManagementProps}
openInstructionOrExpression={this.props.openInstructionOrExpression}
ref={instructionParametersEditor =>
(this._instructionParametersEditor = instructionParametersEditor)

View File

@@ -17,14 +17,9 @@ export default class AudioResourceField extends Component<
}
render() {
if (
!this.props.resourceSources ||
!this.props.onChooseResource ||
!this.props.resourceExternalEditors ||
!this.props.project
) {
if (!this.props.resourceManagementProps || !this.props.project) {
console.error(
'Missing project, resourceSources, onChooseResource or resourceExternalEditors for AudioResourceField'
'Missing project or resourceManagementProps for AudioResourceField'
);
return null;
}
@@ -33,9 +28,7 @@ export default class AudioResourceField extends Component<
<ResourceSelector
margin={this.props.isInline ? 'none' : 'dense'}
project={this.props.project}
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceExternalEditors={this.props.resourceExternalEditors}
resourceManagementProps={this.props.resourceManagementProps}
resourcesLoader={ResourcesLoader}
resourceKind="audio"
fullWidth

View File

@@ -17,14 +17,9 @@ export default class FontResourceField extends Component<
}
render() {
if (
!this.props.resourceSources ||
!this.props.onChooseResource ||
!this.props.resourceExternalEditors ||
!this.props.project
) {
if (!this.props.resourceManagementProps || !this.props.project) {
console.error(
'Missing project, resourceSources, onChooseResource or resourceExternalEditors for BitmapFontResourceField'
'Missing project or resourceManagementProps for BitmapFontResourceField'
);
return null;
}
@@ -33,9 +28,7 @@ export default class FontResourceField extends Component<
<ResourceSelector
margin={this.props.isInline ? 'none' : 'dense'}
project={this.props.project}
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceExternalEditors={this.props.resourceExternalEditors}
resourceManagementProps={this.props.resourceManagementProps}
resourcesLoader={ResourcesLoader}
resourceKind="bitmapFont"
fullWidth

View File

@@ -17,14 +17,9 @@ export default class BitmapFontResourceField extends Component<
}
render() {
if (
!this.props.resourceSources ||
!this.props.onChooseResource ||
!this.props.resourceExternalEditors ||
!this.props.project
) {
if (!this.props.resourceManagementProps || !this.props.project) {
console.error(
'Missing project, resourceSources, onChooseResource or resourceExternalEditors for FontResourceField'
'Missing project or resourceManagementProps for FontResourceField'
);
return null;
}
@@ -33,9 +28,7 @@ export default class BitmapFontResourceField extends Component<
<ResourceSelector
margin={this.props.isInline ? 'none' : 'dense'}
project={this.props.project}
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceExternalEditors={this.props.resourceExternalEditors}
resourceManagementProps={this.props.resourceManagementProps}
resourcesLoader={ResourcesLoader}
resourceKind="font"
fullWidth

View File

@@ -23,14 +23,9 @@ const ImageResourceField = React.forwardRef<
focus,
}));
if (
!props.resourceSources ||
!props.onChooseResource ||
!props.resourceExternalEditors ||
!props.project
) {
if (!props.resourceManagementProps || !props.project) {
console.error(
'Missing project, resourceSources, onChooseResource or resourceExternalEditors for ImageResourceField'
'Missing project or resourceManagementProps for ImageResourceField'
);
return null;
}
@@ -39,9 +34,7 @@ const ImageResourceField = React.forwardRef<
<ResourceSelector
margin={props.isInline ? 'none' : 'dense'}
project={props.project}
resourceSources={props.resourceSources}
onChooseResource={props.onChooseResource}
resourceExternalEditors={props.resourceExternalEditors}
resourceManagementProps={props.resourceManagementProps}
resourcesLoader={ResourcesLoader}
resourceKind="image"
fullWidth

View File

@@ -17,14 +17,9 @@ export default class JsonResourceField extends Component<
}
render() {
if (
!this.props.resourceSources ||
!this.props.onChooseResource ||
!this.props.resourceExternalEditors ||
!this.props.project
) {
if (!this.props.resourceManagementProps || !this.props.project) {
console.error(
'Missing project, resourceSources, onChooseResource or resourceExternalEditors for JsonResourceField'
'Missing project or resourceManagementProps for JsonResourceField'
);
return null;
}
@@ -33,9 +28,7 @@ export default class JsonResourceField extends Component<
<ResourceSelector
margin={this.props.isInline ? 'none' : 'dense'}
project={this.props.project}
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceExternalEditors={this.props.resourceExternalEditors}
resourceManagementProps={this.props.resourceManagementProps}
resourcesLoader={ResourcesLoader}
resourceKind="json"
fullWidth

View File

@@ -1,9 +1,5 @@
// @flow
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../../ResourcesList/ResourceSource';
import { type EventsScope } from '../../InstructionOrExpression/EventsScope.flow';
import { type MessageDescriptor } from '../../Utils/i18n/MessageDescriptor.flow';
@@ -27,9 +23,7 @@ type CommonProps = {|
isInline?: boolean,
onRequestClose?: () => void,
onApply?: () => void,
resourceSources?: Array<ResourceSource>,
onChooseResource?: ChooseResourceFunction,
resourceExternalEditors?: Array<ResourceExternalEditor>,
resourceManagementProps?: ResourceManagementProps,
// Pass the ParameterRenderingService to allow to render nested parameters
parameterRenderingService?: ParameterRenderingServiceType,

View File

@@ -17,14 +17,9 @@ export default class VideoResourceField extends Component<
}
render() {
if (
!this.props.resourceSources ||
!this.props.onChooseResource ||
!this.props.resourceExternalEditors ||
!this.props.project
) {
if (!this.props.resourceManagementProps || !this.props.project) {
console.error(
'Missing project, resourceSources, onChooseResource or resourceExternalEditors for VideoResourceField'
'Missing project or resourceManagementProps for VideoResourceField'
);
return null;
}
@@ -33,9 +28,7 @@ export default class VideoResourceField extends Component<
<ResourceSelector
margin={this.props.isInline ? 'none' : 'dense'}
project={this.props.project}
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceExternalEditors={this.props.resourceExternalEditors}
resourceManagementProps={this.props.resourceManagementProps}
resourcesLoader={ResourcesLoader}
resourceKind="video"
fullWidth

View File

@@ -57,11 +57,7 @@ import EventsContextAnalyzerDialog, {
toEventsContextResult,
} from './EventsContextAnalyzerDialog';
import SearchPanel, { type SearchPanelInterface } from './SearchPanel';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
import EventsSearcher, {
type ReplaceInEventsInputs,
type SearchInEventsInputs,
@@ -121,9 +117,7 @@ type Props = {|
onOpenSettings?: ?() => void,
onOpenExternalEvents: string => void,
onOpenLayout: string => void,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
openInstructionOrExpression: (
extension: gdPlatformExtension,
type: string
@@ -1578,9 +1572,7 @@ export class EventsSheetComponentWithoutHandle extends React.Component<
ensureSingleOnceInstructions(instrsList);
if (this._eventsTree) this._eventsTree.forceEventsUpdate();
}}
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceExternalEditors={this.props.resourceExternalEditors}
resourceManagementProps={this.props.resourceManagementProps}
openInstructionOrExpression={(extension, type) => {
this.closeInstructionEditor();
this.props.openInstructionOrExpression(extension, type);
@@ -1648,9 +1640,7 @@ export class EventsSheetComponentWithoutHandle extends React.Component<
globalObjectsContainer,
objectsContainer,
preferences,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
onCreateEventsFunction,
tutorials,
} = this.props;
@@ -1807,9 +1797,7 @@ export class EventsSheetComponentWithoutHandle extends React.Component<
if (this._searchPanel)
this._searchPanel.markSearchResultsDirty();
}}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
/>
<ContextMenu
ref={eventContextMenu =>

View File

@@ -14,11 +14,7 @@ import { useSerializableObjectCancelableEditor } from '../Utils/SerializableObje
import DismissableAlertMessage from '../UI/DismissableAlertMessage';
import Text from '../UI/Text';
import useForceUpdate from '../Utils/UseForceUpdate';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
import HotReloadPreviewButton, {
type HotReloadPreviewButtonProps,
} from '../HotReload/HotReloadPreviewButton';
@@ -30,9 +26,7 @@ const gd: libGDevelop = global.gd;
type Props = {|
project: gdProject,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
layer: gdLayer,
initialInstances: gdInitialInstancesContainer,
@@ -200,9 +194,7 @@ const LayerEditorDialog = (props: Props) => {
<EffectsList
target="layer"
project={props.project}
resourceSources={props.resourceSources}
onChooseResource={props.onChooseResource}
resourceExternalEditors={props.resourceExternalEditors}
resourceManagementProps={props.resourceManagementProps}
effectsContainer={layer.getEffects()}
onEffectsUpdated={
forceUpdate /*Force update to ensure dialog is properly positioned*/

View File

@@ -8,11 +8,7 @@ import LayerRow from './LayerRow';
import BackgroundColorRow from './BackgroundColorRow';
import { Column, Line } from '../UI/Grid';
import Add from '@material-ui/icons/Add';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
import { type UnsavedChanges } from '../MainFrame/UnsavedChangesContext';
import ScrollView from '../UI/ScrollView';
import { FullSizeMeasurer } from '../UI/FullSizeMeasurer';
@@ -112,9 +108,7 @@ const SortableLayersListBody = SortableContainer(LayersListBody);
type Props = {|
project: gdProject,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
layersContainer: gdLayout,
onEditLayerEffects: (layer: ?gdLayer) => void,
onEditLayer: (layer: ?gdLayer) => void,

View File

@@ -1,17 +1,12 @@
// @flow
import * as React from 'react';
import { type UnsavedChanges } from '../UnsavedChangesContext';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../../ResourcesList/ResourceSource';
import { type ResourceManagementProps } from '../../ResourcesList/ResourceSource';
import type { StorageProvider } from '../../ProjectsStorage';
import { type PreviewDebuggerServer } from '../../Export/PreviewLauncher.flow';
import { type HotReloadPreviewButtonProps } from '../../HotReload/HotReloadPreviewButton';
import { type ResourceExternalEditor } from '../../ResourcesList/ResourceExternalEditor.flow';
import { type FileMetadataAndStorageProviderName } from '../../ProjectsStorage';
import { type ExampleShortHeader } from '../../Utils/GDevelopServices/Example';
import { type OnFetchNewlyAddedResourcesFunction } from '../../ProjectsStorage/ResourceFetcher';
export type EditorContainerExtraProps = {|
// Events function extension editor
@@ -32,10 +27,7 @@ export type RenderEditorContainerProps = {|
extraEditorProps: ?EditorContainerExtraProps,
// Resources:
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
onFetchNewlyAddedResources: OnFetchNewlyAddedResourcesFunction,
resourceManagementProps: ResourceManagementProps,
unsavedChanges: ?UnsavedChanges,

View File

@@ -83,9 +83,7 @@ export class EventsEditorContainer extends React.Component<RenderEditorContainer
ref={editor => (this.editor = editor)}
setToolbar={this.props.setToolbar}
onOpenLayout={this.props.onOpenLayout}
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceExternalEditors={this.props.resourceExternalEditors}
resourceManagementProps={this.props.resourceManagementProps}
openInstructionOrExpression={this.props.openInstructionOrExpression}
onCreateEventsFunction={this.onCreateEventsFunction}
onBeginCreateEventsFunction={this.onBeginCreateEventsFunction}

View File

@@ -133,10 +133,7 @@ export class EventsFunctionsExtensionEditorContainer extends React.Component<Ren
project={project}
eventsFunctionsExtension={eventsFunctionsExtension}
setToolbar={this.props.setToolbar}
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceExternalEditors={this.props.resourceExternalEditors}
onFetchNewlyAddedResources={this.props.onFetchNewlyAddedResources}
resourceManagementProps={this.props.resourceManagementProps}
openInstructionOrExpression={this.props.openInstructionOrExpression}
onCreateEventsFunction={this.props.onCreateEventsFunction}
initiallyFocusedFunctionName={initiallyFocusedFunctionName}

View File

@@ -143,9 +143,7 @@ export class ExternalEventsEditorContainer extends React.Component<
ref={editor => (this.editor = editor)}
setToolbar={this.props.setToolbar}
onOpenLayout={this.props.onOpenLayout}
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceExternalEditors={this.props.resourceExternalEditors}
resourceManagementProps={this.props.resourceManagementProps}
openInstructionOrExpression={this.props.openInstructionOrExpression}
onCreateEventsFunction={this.onCreateEventsFunction}
onBeginCreateEventsFunction={this.onBeginCreateEventsFunction}

View File

@@ -165,10 +165,7 @@ export class ExternalLayoutEditorContainer extends React.Component<
{layout && (
<SceneEditor
setToolbar={this.props.setToolbar}
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceExternalEditors={this.props.resourceExternalEditors}
onFetchNewlyAddedResources={this.props.onFetchNewlyAddedResources}
resourceManagementProps={this.props.resourceManagementProps}
unsavedChanges={this.props.unsavedChanges}
hotReloadPreviewButtonProps={this.props.hotReloadPreviewButtonProps}
ref={editor => (this.editor = editor)}

View File

@@ -50,8 +50,7 @@ export class ResourcesEditorContainer extends React.Component<RenderEditorContai
setToolbar={this.props.setToolbar}
onDeleteResource={this.props.onDeleteResource}
onRenameResource={this.props.onRenameResource}
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceManagementProps={this.props.resourceManagementProps}
ref={editor => (this.editor = editor)}
project={project}
/>

View File

@@ -83,10 +83,7 @@ export class SceneEditorContainer extends React.Component<RenderEditorContainerP
return (
<SceneEditor
setToolbar={this.props.setToolbar}
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceExternalEditors={this.props.resourceExternalEditors}
onFetchNewlyAddedResources={this.props.onFetchNewlyAddedResources}
resourceManagementProps={this.props.resourceManagementProps}
unsavedChanges={this.props.unsavedChanges}
ref={editor => (this.editor = editor)}
project={project}

View File

@@ -2180,17 +2180,18 @@ const MainFrame = (props: Props) => {
return true;
};
const onChooseResource: ChooseResourceFunction = (
options: ChooseResourceOptions
) => {
return new Promise(resolve => {
setChooseResourceOptions(options);
const onResourceChosenSetter: () => (
Promise<Array<gdResource>> | Array<gdResource>
) => void = () => resolve;
setOnResourceChosen(onResourceChosenSetter);
});
};
const onChooseResource: ChooseResourceFunction = React.useCallback(
(options: ChooseResourceOptions) => {
return new Promise(resolve => {
setChooseResourceOptions(options);
const onResourceChosenSetter: () => (
Promise<Array<gdResource>> | Array<gdResource>
) => void = () => resolve;
setOnResourceChosen(onResourceChosenSetter);
});
},
[setOnResourceChosen, setChooseResourceOptions]
);
const setElectronUpdateStatus = (updateStatus: ElectronUpdateStatus) => {
setState(state => ({ ...state, updateStatus }));
@@ -2426,6 +2427,21 @@ const MainFrame = (props: Props) => {
),
});
const resourceManagementProps = React.useMemo(
() => ({
resourceSources,
onChooseResource,
resourceExternalEditors,
onFetchNewlyAddedResources,
}),
[
resourceSources,
onChooseResource,
resourceExternalEditors,
onFetchNewlyAddedResources,
]
);
const showLoader = isLoadingProject || previewLoading;
return (
@@ -2522,9 +2538,7 @@ const MainFrame = (props: Props) => {
freezeUpdate={!projectManagerOpen}
unsavedChanges={unsavedChanges}
hotReloadPreviewButtonProps={hotReloadPreviewButtonProps}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
/>
)}
{!state.currentProject && (
@@ -2603,10 +2617,7 @@ const MainFrame = (props: Props) => {
openEventsEditor: true,
openSceneEditor: false,
}),
resourceSources: props.resourceSources,
onChooseResource,
resourceExternalEditors,
onFetchNewlyAddedResources,
resourceManagementProps,
onCreateEventsFunction,
openInstructionOrExpression,
unsavedChanges: unsavedChanges,
@@ -2713,9 +2724,7 @@ const MainFrame = (props: Props) => {
open
onApply={() => openPlatformSpecificAssetsDialog(false)}
onClose={() => openPlatformSpecificAssetsDialog(false)}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
/>
)}
{!!renderPreviewLauncher &&

View File

@@ -32,9 +32,7 @@ const CustomObjectPropertiesEditor = (props: Props) => {
const {
objectConfiguration,
project,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
unsavedChanges,
} = props;
@@ -91,9 +89,7 @@ const CustomObjectPropertiesEditor = (props: Props) => {
schema={propertiesSchema}
instances={[customObjectConfiguration]}
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
/>
{eventBasedObject &&
mapFor(0, eventBasedObject.getObjectsCount(), i => {
@@ -163,10 +159,8 @@ const CustomObjectPropertiesEditor = (props: Props) => {
<EditorComponent
objectConfiguration={childObjectConfiguration}
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={
resourceExternalEditors
resourceManagementProps={
resourceManagementProps
}
onSizeUpdated={
forceUpdate /*Force update to ensure dialog is properly positionned*/

View File

@@ -1,9 +1,5 @@
// @flow
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../../ResourcesList/ResourceSource';
import { type UnsavedChanges } from '../../MainFrame/UnsavedChangesContext';
/**
@@ -12,9 +8,7 @@ import { type UnsavedChanges } from '../../MainFrame/UnsavedChangesContext';
export type EditorProps = {|
objectConfiguration: gdObjectConfiguration,
project: gdProject,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
onSizeUpdated: () => void,
objectName: string,
unsavedChanges?: UnsavedChanges,

View File

@@ -22,9 +22,7 @@ const ObjectPropertiesEditor = (props: Props) => {
const {
objectConfiguration,
project,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
unsavedChanges,
} = props;
@@ -79,9 +77,7 @@ const ObjectPropertiesEditor = (props: Props) => {
schema={propertiesSchema}
instances={[objectConfigurationAsGd]}
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
/>
</React.Fragment>
) : (

View File

@@ -17,9 +17,7 @@ export default class PanelSpriteEditor extends React.Component<
const {
objectConfiguration,
project,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
} = this.props;
const panelSpriteConfiguration = gd.asPanelSpriteConfiguration(
objectConfiguration
@@ -29,9 +27,7 @@ export default class PanelSpriteEditor extends React.Component<
<ColumnStackLayout>
<ResourceSelectorWithThumbnail
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
resourceKind="image"
resourceName={panelSpriteConfiguration.getTexture()}
onChange={resourceName => {

View File

@@ -27,9 +27,7 @@ export default class ParticleEmitterEditor extends React.Component<
const {
objectConfiguration,
project,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
} = this.props;
const particleEmitterConfiguration = gd.asParticleEmitterConfiguration(
objectConfiguration
@@ -119,11 +117,9 @@ export default class ParticleEmitterEditor extends React.Component<
gd.ParticleEmitterObject.Quad && (
<ResourceSelectorWithThumbnail
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceManagementProps={resourceManagementProps}
resourceKind="image"
resourceName={particleEmitterConfiguration.getParticleTexture()}
resourceExternalEditors={resourceExternalEditors}
onChange={resourceName => {
particleEmitterConfiguration.setParticleTexture(resourceName);
this.forceUpdate();

View File

@@ -1,6 +1,6 @@
// @flow
import { Trans } from '@lingui/macro';
import { type I18n as I18nType } from '@lingui/core';
import React, { Component } from 'react';
import { SortableContainer, SortableElement } from 'react-sortable-hoc';
import { mapFor } from '../../../Utils/MapFor';
@@ -19,12 +19,13 @@ import {
import ResourcesLoader from '../../../ResourcesLoader';
import {
type ResourceSource,
type ChooseResourceFunction,
type ResourceManagementProps,
} from '../../../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../../../ResourcesList/ResourceExternalEditor.flow';
import { applyResourceDefaults } from '../../../ResourcesList/ResourceUtils';
import FlatButton from '../../../UI/FlatButton';
import ThemeConsumer from '../../../UI/Theme/ThemeConsumer';
import ElementWithMenu from '../../../UI/Menu/ElementWithMenu';
const gd: libGDevelop = global.gd;
const path = require('path');
@@ -45,26 +46,47 @@ const styles = {
},
};
const AddSpriteButton = SortableElement(({ displayHint, onAdd }) => {
return (
<ThemeConsumer>
{muiTheme => (
<div
style={{
...thumbnailContainerStyle,
backgroundColor: muiTheme.list.itemsBackgroundColor,
}}
>
<FlatButton
onClick={onAdd}
label={<Trans>Add</Trans>}
leftIcon={<Add />}
/>
</div>
)}
</ThemeConsumer>
);
});
type AddSpriteButtonProps = {|
onAdd: (resourceSource: ResourceSource) => void,
resourceSources: Array<ResourceSource>,
|};
const AddSpriteButton = SortableElement(
({ onAdd, resourceSources }: AddSpriteButtonProps) => {
return (
<ThemeConsumer>
{muiTheme => (
<div
style={{
...thumbnailContainerStyle,
backgroundColor: muiTheme.list.itemsBackgroundColor,
}}
>
<ElementWithMenu
element={
<FlatButton
onClick={() => {
/* Will be replaced by ElementWithMenu. */
}}
label={<Trans>Add</Trans>}
leftIcon={<Add />}
/>
}
buildMenuTemplate={(i18n: I18nType) =>
resourceSources
.filter(source => source.kind === 'image')
.map(source => ({
label: i18n._(source.displayName),
click: () => onAdd(source),
}))
}
/>
</div>
)}
</ThemeConsumer>
);
}
);
const SortableSpriteThumbnail = SortableElement(
({ sprite, project, resourcesLoader, selected, onSelect, onContextMenu }) => {
@@ -89,6 +111,7 @@ const SortableList = SortableContainer(
project,
resourcesLoader,
onAddSprite,
resourceSources,
selectedSprites,
onSelectSprite,
onSpriteContextMenu,
@@ -118,6 +141,7 @@ const SortableList = SortableContainer(
disabled
index={spritesCount}
onAdd={onAddSprite}
resourceSources={resourceSources}
/>,
]}
</div>
@@ -152,9 +176,7 @@ type Props = {|
direction: gdDirection,
project: gdProject,
resourcesLoader: typeof ResourcesLoader,
resourceSources: Array<ResourceSource>,
resourceExternalEditors: Array<ResourceExternalEditor>,
onChooseResource: ChooseResourceFunction,
resourceManagementProps: ResourceManagementProps,
onSpriteContextMenu: (x: number, y: number, sprite: gdSprite) => void,
selectedSprites: {
[number]: boolean,
@@ -178,51 +200,43 @@ export default class SpritesList extends Component<Props, void> {
this.forceUpdate();
};
onAddSprite = () => {
const {
resourceSources,
onChooseResource,
project,
direction,
} = this.props;
if (!resourceSources) return;
const sources = resourceSources.filter(source => source.kind === 'image');
if (!sources.length) return;
onAddSprite = async (resourceSource: ResourceSource) => {
const { resourceManagementProps, project, direction } = this.props;
const {
allDirectionSpritesHaveSameCollisionMasks,
allDirectionSpritesHaveSamePoints,
} = checkDirectionPointsAndCollisionsMasks(direction);
onChooseResource({
// Should be updated once new sources are introduced in the desktop app.
// Search for "sources[0]" in the codebase for other places like this.
initialSourceName: sources[0].name,
const resources = await resourceManagementProps.onChooseResource({
initialSourceName: resourceSource.name,
multiSelection: true,
resourceKind: 'image',
}).then(resources => {
resources.forEach(resource => {
applyResourceDefaults(project, resource);
project.getResourcesManager().addResource(resource);
const sprite = new gd.Sprite();
sprite.setImageName(resource.getName());
if (allDirectionSpritesHaveSamePoints) {
copySpritePoints(direction.getSprite(0), sprite);
}
if (allDirectionSpritesHaveSameCollisionMasks) {
copySpritePolygons(direction.getSprite(0), sprite);
}
direction.addSprite(sprite);
sprite.delete();
});
// Important, we are responsible for deleting the resources that were given to us.
// Otherwise we have a memory leak, as calling addResource is making a copy of the resource.
resources.forEach(resource => resource.delete());
this.forceUpdate();
});
resources.forEach(resource => {
applyResourceDefaults(project, resource);
project.getResourcesManager().addResource(resource);
const sprite = new gd.Sprite();
sprite.setImageName(resource.getName());
if (allDirectionSpritesHaveSamePoints) {
copySpritePoints(direction.getSprite(0), sprite);
}
if (allDirectionSpritesHaveSameCollisionMasks) {
copySpritePolygons(direction.getSprite(0), sprite);
}
direction.addSprite(sprite);
sprite.delete();
});
// Important, we are responsible for deleting the resources that were given to us.
// Otherwise we have a memory leak, as calling addResource is making a copy of the resource.
resources.forEach(resource => resource.delete());
this.forceUpdate();
await resourceManagementProps.onFetchNewlyAddedResources();
};
editWith = (externalEditor: ResourceExternalEditor) => {
@@ -324,7 +338,9 @@ export default class SpritesList extends Component<Props, void> {
direction={this.props.direction}
resourcesLoader={this.props.resourcesLoader}
project={this.props.project}
resourceExternalEditors={this.props.resourceExternalEditors}
resourceExternalEditors={
this.props.resourceManagementProps.resourceExternalEditors
}
onEditWith={this.editWith}
/>
</MiniToolbar>
@@ -334,6 +350,7 @@ export default class SpritesList extends Component<Props, void> {
project={this.props.project}
onSortEnd={this.onSortEnd}
onAddSprite={this.onAddSprite}
resourceSources={this.props.resourceManagementProps.resourceSources}
selectedSprites={this.props.selectedSprites}
onSelectSprite={this.props.onSelectSprite}
onSpriteContextMenu={this.props.onSpriteContextMenu}

View File

@@ -29,11 +29,7 @@ import {
duplicateSpritesInAnimation,
} from './Utils/SpriteObjectHelper';
import { type EditorProps } from '../EditorProps.flow';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../../../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../../../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../../../ResourcesList/ResourceSource';
import { Column } from '../../../UI/Grid';
import { ResponsiveLineStackLayout } from '../../../UI/Layout';
import ScrollView from '../../../UI/ScrollView';
@@ -48,9 +44,7 @@ type AnimationProps = {|
animation: gdAnimation,
id: number,
project: gdProject,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
onRemove: () => void,
resourcesLoader: typeof ResourcesLoader,
onSpriteContextMenu: (x: number, y: number, sprite: gdSprite) => void,
@@ -72,10 +66,8 @@ class Animation extends React.Component<AnimationProps, void> {
animation,
id,
project,
resourceSources,
onRemove,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
resourcesLoader,
onSpriteContextMenu,
selectedSprites,
@@ -113,9 +105,7 @@ class Animation extends React.Component<AnimationProps, void> {
key={i}
project={project}
resourcesLoader={resourcesLoader}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
onSpriteContextMenu={onSpriteContextMenu}
selectedSprites={selectedSprites}
onSelectSprite={onSelectSprite}
@@ -144,9 +134,7 @@ const SortableAnimationsList = SortableContainer(
onChangeAnimationName,
project,
resourcesLoader,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
extraBottomTools,
onSpriteContextMenu,
selectedSprites,
@@ -168,9 +156,7 @@ const SortableAnimationsList = SortableContainer(
animation={animation}
project={project}
resourcesLoader={resourcesLoader}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
onRemove={() => onRemoveAnimation(i)}
onChangeName={newName => onChangeAnimationName(i, newName)}
onSpriteContextMenu={onSpriteContextMenu}
@@ -191,9 +177,7 @@ const SortableAnimationsList = SortableContainer(
type AnimationsListContainerProps = {|
spriteConfiguration: gdSpriteObject,
project: gdProject,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
resourcesLoader: typeof ResourcesLoader,
extraBottomTools: React.Node,
onSizeUpdated: () => void,
@@ -343,9 +327,7 @@ class AnimationsListContainer extends React.Component<
selectedSprites={this.state.selectedSprites}
onSelectSprite={this.selectSprite}
resourcesLoader={this.props.resourcesLoader}
resourceSources={this.props.resourceSources}
resourceExternalEditors={this.props.resourceExternalEditors}
onChooseResource={this.props.onChooseResource}
resourceManagementProps={this.props.resourceManagementProps}
useDragHandle
lockAxis="y"
axis="y"
@@ -389,9 +371,7 @@ class AnimationsListContainer extends React.Component<
export default function SpriteEditor({
objectConfiguration,
project,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
onSizeUpdated,
objectName,
}: EditorProps) {
@@ -409,9 +389,7 @@ export default function SpriteEditor({
<AnimationsListContainer
spriteConfiguration={spriteConfiguration}
resourcesLoader={ResourcesLoader}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
project={project}
objectName={objectName}
onSizeUpdated={onSizeUpdated}

View File

@@ -32,9 +32,7 @@ export default class TextEditor extends React.Component<EditorProps, void> {
const {
objectConfiguration,
project,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
} = this.props;
const textObjectConfiguration = gd.asTextObjectConfiguration(
objectConfiguration
@@ -104,9 +102,7 @@ export default class TextEditor extends React.Component<EditorProps, void> {
<ResourceSelector
margin="none"
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
resourcesLoader={ResourcesLoader}
resourceKind="font"
fullWidth

View File

@@ -16,9 +16,7 @@ export default class TiledSpriteEditor extends React.Component<
const {
objectConfiguration,
project,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
} = this.props;
const tiledSpriteConfiguration = gd.asTiledSpriteConfiguration(
objectConfiguration
@@ -28,11 +26,9 @@ export default class TiledSpriteEditor extends React.Component<
<ColumnStackLayout>
<ResourceSelectorWithThumbnail
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceManagementProps={resourceManagementProps}
resourceKind="image"
resourceName={tiledSpriteConfiguration.getTexture()}
resourceExternalEditors={resourceExternalEditors}
onChange={resourceName => {
tiledSpriteConfiguration.setTexture(resourceName);
this.forceUpdate();

View File

@@ -12,11 +12,7 @@ import { useSerializableObjectCancelableEditor } from '../Utils/SerializableObje
import SemiControlledTextField from '../UI/SemiControlledTextField';
import { Column, Line } from '../UI/Grid';
import { type EditorProps } from './Editors/EditorProps.flow';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
import { type UnsavedChanges } from '../MainFrame/UnsavedChangesContext';
import useForceUpdate from '../Utils/UseForceUpdate';
import HotReloadPreviewButton, {
@@ -48,9 +44,7 @@ type Props = {|
// Passed down to object editors:
project: gdProject,
onComputeAllVariableNames: () => Array<string>,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
unsavedChanges?: UnsavedChanges,
onUpdateBehaviorsSharedData: () => void,
initialTab: ?ObjectEditorTab,
@@ -209,9 +203,7 @@ const InnerDialog = (props: InnerDialogProps) => {
<EditorComponent
objectConfiguration={props.object.getConfiguration()}
project={props.project}
resourceSources={props.resourceSources}
onChooseResource={props.onChooseResource}
resourceExternalEditors={props.resourceExternalEditors}
resourceManagementProps={props.resourceManagementProps}
onSizeUpdated={
forceUpdate /*Force update to ensure dialog is properly positionned*/
}
@@ -223,9 +215,7 @@ const InnerDialog = (props: InnerDialogProps) => {
<BehaviorsEditor
object={props.object}
project={props.project}
resourceSources={props.resourceSources}
onChooseResource={props.onChooseResource}
resourceExternalEditors={props.resourceExternalEditors}
resourceManagementProps={props.resourceManagementProps}
onSizeUpdated={
forceUpdate /*Force update to ensure dialog is properly positionned*/
}
@@ -260,9 +250,7 @@ const InnerDialog = (props: InnerDialogProps) => {
<EffectsList
target="object"
project={props.project}
resourceSources={props.resourceSources}
onChooseResource={props.onChooseResource}
resourceExternalEditors={props.resourceExternalEditors}
resourceManagementProps={props.resourceManagementProps}
effectsContainer={props.object.getEffects()}
onEffectsUpdated={
forceUpdate /*Force update to ensure dialog is properly positionned*/

View File

@@ -41,13 +41,8 @@ import {
import { type UnsavedChanges } from '../MainFrame/UnsavedChangesContext';
import { type HotReloadPreviewButtonProps } from '../HotReload/HotReloadPreviewButton';
import { useScreenType } from '../UI/Reponsive/ScreenTypeMeasurer';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import { type OnFetchNewlyAddedResourcesFunction } from '../ProjectsStorage/ResourceFetcher';
import { getInstanceCountInLayoutForObject } from '../Utils/Layout';
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
const gd: libGDevelop = global.gd;
const styles = {
@@ -106,11 +101,8 @@ type Props = {|
project: gdProject,
layout: ?gdLayout,
objectsContainer: gdObjectsContainer,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
onFetchNewlyAddedResources: OnFetchNewlyAddedResourcesFunction,
onSelectAllInstancesOfObjectInLayout?: string => void,
resourceManagementProps: ResourceManagementProps,
onDeleteObject: (
objectWithContext: ObjectWithContext,
cb: (boolean) => void
@@ -639,11 +631,8 @@ export default class ObjectsList extends React.Component<Props, State> {
project,
layout,
objectsContainer,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
selectedObjectTags,
onFetchNewlyAddedResources,
} = this.props;
const { searchText, tagEditedObject } = this.state;
@@ -737,10 +726,7 @@ export default class ObjectsList extends React.Component<Props, State> {
project={project}
layout={layout}
objectsContainer={objectsContainer}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
onFetchNewlyAddedResources={onFetchNewlyAddedResources}
resourceManagementProps={resourceManagementProps}
/>
)}
{tagEditedObject && (

View File

@@ -2,6 +2,7 @@
import { Trans } from '@lingui/macro';
import { t } from '@lingui/macro';
import { I18n } from '@lingui/react';
import { type I18n as I18nType } from '@lingui/core';
import * as React from 'react';
import FlatButton from '../UI/FlatButton';
@@ -12,14 +13,14 @@ import ResourcesLoader from '../ResourcesLoader';
import ResourceSelectorWithThumbnail from '../ResourcesList/ResourceSelectorWithThumbnail';
import {
type ResourceSource,
type ChooseResourceFunction,
type ResourceManagementProps,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import { resizeImage, isResizeSupported } from './ImageResizer';
import { showErrorBox } from '../UI/Messages/MessageBox';
import optionalRequire from '../Utils/OptionalRequire';
import Text from '../UI/Text';
import { ColumnStackLayout } from '../UI/Layout';
import ElementWithMenu from '../UI/Menu/ElementWithMenu';
const path = optionalRequire('path');
const gd: libGDevelop = global.gd;
@@ -28,9 +29,7 @@ type Props = {|
open: boolean,
onClose: Function,
onApply: Function,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
|};
type State = {|
@@ -109,123 +108,132 @@ export default class PlatformSpecificAssetsDialog extends React.Component<
}
}
_generateFromFile = () => {
const { project, resourceSources, onChooseResource } = this.props;
_generateFromFile = (resourceSource: ResourceSource) => {
const { project, resourceManagementProps } = this.props;
const sources = resourceSources.filter(source => source.kind === 'image');
if (!sources.length) return;
if (!resourceSource.name.startsWith('local-file-opener')) {
throw new Error('Only local files are supported for generating icons.');
}
onChooseResource({
// Should be updated once new sources are introduced in the desktop app.
// Search for "sources[0]" in the codebase for other places like this.
initialSourceName: sources[0].name,
multiSelection: false,
resourceKind: 'image',
}).then(resources => {
if (!resources.length || !path) {
return;
}
const resourcesManager = project.getResourcesManager();
const projectPath = path.dirname(project.getProjectFile());
const fullPath = path.resolve(projectPath, resources[0].getFile());
// Important, we are responsible for deleting the resources that were given to us.
// Otherwise we have a memory leak.
resources.forEach(resource => resource.delete());
Promise.all([
...desktopSizes.map(size =>
resizeImage(
fullPath,
path.join(projectPath, `desktop-icon-${size}.png`),
{
width: size,
height: size,
}
)
),
...androidSizes.map(size =>
resizeImage(
fullPath,
path.join(projectPath, `android-icon-${size}.png`),
{
width: size,
height: size,
}
)
),
resizeImage(
fullPath,
path.join(projectPath, 'android-windowSplashScreenAnimatedIcon.png'),
{
width: androidWindowSplashScreenAnimatedIconRecommendedSize,
height: androidWindowSplashScreenAnimatedIconRecommendedSize,
transparentBorderSize:
androidWindowSplashScreenAnimatedIconRecommendedSize / 6,
}
),
...iosSizes.map(size =>
resizeImage(
fullPath,
path.join(projectPath, `ios-icon-${size}.png`),
{
width: size,
height: size,
}
)
),
]).then(results => {
if (results.indexOf(false) !== -1) {
showErrorBox({
message: 'Some icons could not be generated!',
rawError: undefined,
errorId: 'icon-generation-error',
doNotReport: true,
});
resourceManagementProps
.onChooseResource({
initialSourceName: resourceSource.name,
multiSelection: false,
resourceKind: 'image',
})
.then(resources => {
if (!resources.length || !path) {
return;
}
// Add resources to the game
const allResourcesNames = [
...desktopSizes.map(size => `desktop-icon-${size}.png`),
...androidSizes.map(size => `android-icon-${size}.png`),
'android-windowSplashScreenAnimatedIcon.png',
...iosSizes.map(size => `ios-icon-${size}.png`),
];
allResourcesNames.forEach(resourceName => {
if (!resourcesManager.hasResource(resourceName)) {
const imageResource = new gd.ImageResource();
imageResource.setFile(resourceName);
imageResource.setName(resourceName);
const resourcesManager = project.getResourcesManager();
const projectPath = path.dirname(project.getProjectFile());
const fullPath = path.resolve(projectPath, resources[0].getFile());
resourcesManager.addResource(imageResource);
// Important, we are responsible for deleting the resources that were given to us.
// Otherwise we have a memory leak.
resources.forEach(resource => resource.delete());
// Important, we are responsible for deleting the resources that we created
// Otherwise we have a memory leak, as calling addResource is making a copy of the resource.
imageResource.delete();
} else {
resourcesManager.getResource(resourceName).setFile(resourceName);
Promise.all([
...desktopSizes.map(size =>
resizeImage(
fullPath,
path.join(projectPath, `desktop-icon-${size}.png`),
{
width: size,
height: size,
}
)
),
...androidSizes.map(size =>
resizeImage(
fullPath,
path.join(projectPath, `android-icon-${size}.png`),
{
width: size,
height: size,
}
)
),
resizeImage(
fullPath,
path.join(
projectPath,
'android-windowSplashScreenAnimatedIcon.png'
),
{
width: androidWindowSplashScreenAnimatedIconRecommendedSize,
height: androidWindowSplashScreenAnimatedIconRecommendedSize,
transparentBorderSize:
androidWindowSplashScreenAnimatedIconRecommendedSize / 6,
}
),
...iosSizes.map(size =>
resizeImage(
fullPath,
path.join(projectPath, `ios-icon-${size}.png`),
{
width: size,
height: size,
}
)
),
]).then(results => {
if (results.indexOf(false) !== -1) {
showErrorBox({
message: 'Some icons could not be generated!',
rawError: undefined,
errorId: 'icon-generation-error',
doNotReport: true,
});
return;
}
});
// Make sure the resources are (re)loaded.
ResourcesLoader.burstUrlsCacheForResources(project, allResourcesNames);
setTimeout(() => {
this.setState({
desktopIconResourceNames: desktopSizes.map(
size => `desktop-icon-${size}.png`
),
androidIconResourceNames: androidSizes.map(
size => `android-icon-${size}.png`
),
androidWindowSplashScreenAnimatedIconResourceName:
'android-windowSplashScreenAnimatedIcon.png',
iosIconResourceNames: iosSizes.map(size => `ios-icon-${size}.png`),
// Add resources to the game
const allResourcesNames = [
...desktopSizes.map(size => `desktop-icon-${size}.png`),
...androidSizes.map(size => `android-icon-${size}.png`),
'android-windowSplashScreenAnimatedIcon.png',
...iosSizes.map(size => `ios-icon-${size}.png`),
];
allResourcesNames.forEach(resourceName => {
if (!resourcesManager.hasResource(resourceName)) {
const imageResource = new gd.ImageResource();
imageResource.setFile(resourceName);
imageResource.setName(resourceName);
resourcesManager.addResource(imageResource);
// Important, we are responsible for deleting the resources that we created
// Otherwise we have a memory leak, as calling addResource is making a copy of the resource.
imageResource.delete();
} else {
resourcesManager.getResource(resourceName).setFile(resourceName);
}
});
}, 200 /* Let a bit of time so that image files can be found */);
// Make sure the resources are (re)loaded.
ResourcesLoader.burstUrlsCacheForResources(
project,
allResourcesNames
);
setTimeout(() => {
this.setState({
desktopIconResourceNames: desktopSizes.map(
size => `desktop-icon-${size}.png`
),
androidIconResourceNames: androidSizes.map(
size => `android-icon-${size}.png`
),
androidWindowSplashScreenAnimatedIconResourceName:
'android-windowSplashScreenAnimatedIcon.png',
iosIconResourceNames: iosSizes.map(
size => `ios-icon-${size}.png`
),
});
}, 200 /* Let a bit of time so that image files can be found */);
});
});
});
};
onApply = () => {
@@ -287,12 +295,7 @@ export default class PlatformSpecificAssetsDialog extends React.Component<
onClick={this.onApply}
/>,
];
const {
project,
resourceSources,
onChooseResource,
resourceExternalEditors,
} = this.props;
const { project, resourceManagementProps } = this.props;
const {
thumbnailResourceName,
desktopIconResourceNames,
@@ -310,29 +313,29 @@ export default class PlatformSpecificAssetsDialog extends React.Component<
onApply={this.onApply}
>
<ColumnStackLayout noMargin>
<Text size="sub-title">
<Trans>Liluo.io thumbnail</Trans>
</Text>
<ResourceSelectorWithThumbnail
floatingLabelText={`Liluo.io thumbnail (1920x1080 px)`}
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceKind="image"
resourceName={thumbnailResourceName}
onChange={resourceName => {
this.setState({
thumbnailResourceName: resourceName,
});
}}
/>
<Line justifyContent="center">
<Line justifyContent="center" noMargin>
{isResizeSupported() ? (
<RaisedButton
primary
label={<Trans>Generate icons from a file</Trans>}
onClick={this._generateFromFile}
<ElementWithMenu
element={
<RaisedButton
primary
label={<Trans>Generate icons from a file</Trans>}
onClick={() => {
/* Will be replaced by ElementWithMenu */
}}
/>
}
buildMenuTemplate={(i18n: I18nType) =>
resourceManagementProps.resourceSources
.filter(source => source.kind === 'image')
.filter(source =>
source.name.startsWith('local-file-opener')
)
.map(source => ({
label: i18n._(source.displayName),
click: () => this._generateFromFile(source),
}))
}
/>
) : (
<Text>
@@ -343,6 +346,21 @@ export default class PlatformSpecificAssetsDialog extends React.Component<
</Text>
)}
</Line>
<Text size="sub-title">
<Trans>Liluo.io thumbnail</Trans>
</Text>
<ResourceSelectorWithThumbnail
floatingLabelText={`Liluo.io thumbnail (1920x1080 px)`}
project={project}
resourceManagementProps={resourceManagementProps}
resourceKind="image"
resourceName={thumbnailResourceName}
onChange={resourceName => {
this.setState({
thumbnailResourceName: resourceName,
});
}}
/>
<Text size="sub-title">
<Trans>Desktop (Windows, macOS and Linux) icon</Trans>
</Text>
@@ -351,9 +369,7 @@ export default class PlatformSpecificAssetsDialog extends React.Component<
key={size}
floatingLabelText={`Desktop icon (${size}x${size} px)`}
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
resourceKind="image"
resourceName={desktopIconResourceNames[index]}
onChange={resourceName => {
@@ -373,9 +389,7 @@ export default class PlatformSpecificAssetsDialog extends React.Component<
<ResourceSelectorWithThumbnail
floatingLabelText={`Android 12+ splashscreen icon (576x576 px)`}
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
resourceKind="image"
resourceName={androidWindowSplashScreenAnimatedIconResourceName}
onChange={resourceName => {
@@ -394,9 +408,7 @@ export default class PlatformSpecificAssetsDialog extends React.Component<
key={size}
floatingLabelText={`Android icon (${size}x${size} px)`}
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
resourceKind="image"
resourceName={androidIconResourceNames[index]}
onChange={resourceName => {
@@ -416,11 +428,9 @@ export default class PlatformSpecificAssetsDialog extends React.Component<
key={size}
floatingLabelText={`iOS icon (${size}x${size} px)`}
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceManagementProps={resourceManagementProps}
resourceKind="image"
resourceName={iosIconResourceNames[index]}
resourceExternalEditors={resourceExternalEditors}
onChange={resourceName => {
const newIcons = [...iosIconResourceNames];
newIcons[index] = resourceName;

View File

@@ -14,11 +14,7 @@ import {
} from '../Utils/ColorTransformer';
import useForceUpdate from '../Utils/UseForceUpdate';
import ResourceSelectorWithThumbnail from '../ResourcesList/ResourceSelectorWithThumbnail';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
import SelectField from '../UI/SelectField';
import SelectOption from '../UI/SelectOption';
import Text from '../UI/Text';
@@ -29,18 +25,14 @@ type Props = {
// For resources:
project: gdProject,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
};
export const LoadingScreenEditor = ({
loadingScreen,
onChangeSubscription,
project,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
}: Props) => {
const subscriptionChecker = React.useRef<?SubscriptionChecker>(null);
const forceUpdate = useForceUpdate();
@@ -56,9 +48,7 @@ export const LoadingScreenEditor = ({
<ResourceSelectorWithThumbnail
floatingLabelText={<Trans>Background image</Trans>}
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
resourceKind="image"
resourceName={loadingScreen.getBackgroundImageResourceName()}
onChange={resourceName => {

View File

@@ -27,11 +27,7 @@ import AlertMessage from '../UI/AlertMessage';
import { GameRegistration } from '../GameDashboard/GameRegistration';
import { Tab, Tabs } from '../UI/Tabs';
import { LoadingScreenEditor } from './LoadingScreenEditor';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
import {
type HotReloadPreviewButtonProps,
NewPreviewIcon,
@@ -49,9 +45,7 @@ type Props = {|
hotReloadPreviewButtonProps?: ?HotReloadPreviewButtonProps,
// For resources:
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
|};
type ProjectProperties = {|
@@ -597,9 +591,7 @@ function ProjectPropertiesDialog(props: Props) {
props.onChangeSubscription();
}}
project={project}
resourceSources={props.resourceSources}
onChooseResource={props.onChooseResource}
resourceExternalEditors={props.resourceExternalEditors}
resourceManagementProps={props.resourceManagementProps}
/>
)}
</Dialog>

View File

@@ -47,11 +47,7 @@ import ProjectManagerCommands from './ProjectManagerCommands';
import { type HotReloadPreviewButtonProps } from '../HotReload/HotReloadPreviewButton';
import { type ExtensionShortHeader } from '../Utils/GDevelopServices/Extension';
import EventsRootVariablesFinder from '../Utils/EventsRootVariablesFinder';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
import InstalledExtensionDetails from './InstalledExtensionDetails';
import {
Item,
@@ -111,9 +107,7 @@ type Props = {|
onInstallExtension: ExtensionShortHeader => void,
// For resources:
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
|};
type State = {|
@@ -1112,9 +1106,7 @@ export default class ProjectManager extends React.Component<Props, State> {
onApply={this.props.onSaveProjectProperties}
onPropertiesApplied={this._onProjectPropertiesApplied}
onChangeSubscription={this.props.onChangeSubscription}
resourceSources={this.props.resourceSources}
onChooseResource={this.props.onChooseResource}
resourceExternalEditors={this.props.resourceExternalEditors}
resourceManagementProps={this.props.resourceManagementProps}
hotReloadPreviewButtonProps={
this.props.hotReloadPreviewButtonProps
}

View File

@@ -1,5 +1,6 @@
// @flow
import { Trans } from '@lingui/macro';
import { type I18n as I18nType } from '@lingui/core';
import * as React from 'react';
import SemiControlledTextField from '../UI/SemiControlledTextField';
import InlineCheckbox from '../UI/InlineCheckbox';
@@ -13,13 +14,11 @@ import ColorField from '../UI/ColorField';
import { MarkdownText } from '../UI/MarkdownText';
import { rgbOrHexToRGBString } from '../Utils/ColorTransformer';
import FormHelperText from '@material-ui/core/FormHelperText';
import { type MenuItemTemplate } from '../UI/Menu/Menu.flow';
import {
type ResourceKind,
type ResourceSource,
type ChooseResourceFunction,
type ResourceManagementProps,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import {
TextFieldWithButtonLayout,
ResponsiveLineStackLayout,
@@ -32,6 +31,7 @@ import UnsavedChangesContext, {
import { Line, Spacer } from '../UI/Grid';
import Text from '../UI/Text';
import useForceUpdate from '../Utils/UseForceUpdate';
import ElementWithMenu from '../UI/Menu/ElementWithMenu';
// An "instance" here is the objects for which properties are shown
export type Instance = Object; // This could be improved using generics.
@@ -44,7 +44,7 @@ export type ValueFieldCommonProperties = {|
getDescription?: Instance => string,
getExtraDescription?: Instance => string,
disabled?: boolean | ((instances: Array<gdInitialInstance>) => boolean),
onEditButtonClick?: Instance => void,
onEditButtonBuildMenuTemplate?: (i18n: I18nType) => Array<MenuItemTemplate>,
|};
// "Primitive" value fields are "simple" fields.
@@ -141,9 +141,7 @@ type Props = {|
// Optional context:
project?: ?gdProject,
resourceSources?: ?Array<ResourceSource>,
onChooseResource?: ?ChooseResourceFunction,
resourceExternalEditors?: ?Array<ResourceExternalEditor>,
resourceManagementProps?: ?ResourceManagementProps,
|};
const styles = {
@@ -230,9 +228,7 @@ const PropertiesEditor = ({
renderExtraDescriptionText,
unsavedChanges,
project,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
}: Props) => {
const forceUpdate = useForceUpdate();
@@ -358,7 +354,7 @@ const PropertiesEditor = ({
/>
);
} else {
const { onEditButtonClick, setValue } = field;
const { onEditButtonBuildMenuTemplate, setValue } = field;
return (
<TextFieldWithButtonLayout
key={field.name}
@@ -378,14 +374,21 @@ const PropertiesEditor = ({
/>
)}
renderButton={style =>
onEditButtonClick ? (
<RaisedButton
style={style}
primary
disabled={instances.length !== 1}
icon={<Edit />}
label={<Trans>Edit</Trans>}
onClick={() => onEditButtonClick(instances[0])}
onEditButtonBuildMenuTemplate ? (
<ElementWithMenu
element={
<RaisedButton
style={style}
primary
disabled={instances.length !== 1}
icon={<Edit />}
label={<Trans>Edit</Trans>}
onClick={() => {
/* Will be replaced by ElementWithMenu */
}}
/>
}
buildMenuTemplate={onEditButtonBuildMenuTemplate}
/>
) : null
}
@@ -479,14 +482,9 @@ const PropertiesEditor = ({
);
const renderResourceField = (field: ResourceField) => {
if (
!project ||
!resourceSources ||
!onChooseResource ||
!resourceExternalEditors
) {
if (!project || !resourceManagementProps) {
console.error(
'You tried to display a resource field in a PropertiesEditor that does not support display resources. If you need to display resources, pass additional props (project, resourceSources, onChooseResource, resourceExternalEditors).'
'You tried to display a resource field in a PropertiesEditor that does not support display resources. If you need to display resources, pass additional props (project, resourceManagementProps).'
);
return null;
}
@@ -496,9 +494,7 @@ const PropertiesEditor = ({
<ResourceSelector
key={field.name}
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
resourcesLoader={ResourcesLoader}
resourceKind={field.resourceKind}
fullWidth
@@ -582,9 +578,7 @@ const PropertiesEditor = ({
{unsavedChanges => (
<PropertiesEditor
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
schema={field.children}
instances={instances}
mode="row"
@@ -613,9 +607,7 @@ const PropertiesEditor = ({
{unsavedChanges => (
<PropertiesEditor
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
schema={field.children}
instances={instances}
mode="column"

View File

@@ -1,5 +1,6 @@
// @flow
import { Trans } from '@lingui/macro';
import { type I18n as I18nType } from '@lingui/core';
import * as React from 'react';
import Background from '../../UI/Background';
@@ -12,7 +13,7 @@ import { type Schema } from '../../PropertiesEditor';
import {
type ResourceSource,
type ChooseResourceFunction,
type ResourceManagementProps,
} from '../../ResourcesList/ResourceSource';
const styles = {
@@ -29,8 +30,7 @@ type Props = {|
resourcesLoader: typeof ResourcesLoader,
resources: Array<gdResource>,
onResourcePathUpdated: () => void,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceManagementProps: ResourceManagementProps,
|};
export default class ResourcePropertiesEditor extends React.Component<
@@ -52,7 +52,13 @@ export default class ResourcePropertiesEditor extends React.Component<
getValue: (resource: gdResource) => resource.getFile(),
setValue: (resource: gdResource, newValue: string) =>
resource.setFile(newValue),
onEditButtonClick: () => this._chooseResourcePath(),
onEditButtonBuildMenuTemplate: (i18n: I18nType) =>
this.props.resourceManagementProps.resourceSources
.filter(source => source.kind === this.props.resources[0].getKind())
.map(source => ({
label: i18n._(source.displayName),
click: () => this._chooseResourcePath(source),
})),
},
];
@@ -68,35 +74,30 @@ export default class ResourcePropertiesEditor extends React.Component<
);
}
_chooseResourcePath = () => {
_chooseResourcePath = async (resourceSource: ResourceSource) => {
const {
resources,
onResourcePathUpdated,
onChooseResource,
resourceSources,
resourceManagementProps,
} = this.props;
const resource = resources[0];
const sources = resourceSources.filter(
source => source.kind === resource.getKind()
);
if (!sources.length) return;
onChooseResource({
// Should be updated once new sources are introduced in the desktop app.
// Search for "sources[0]" in the codebase for other places like this.
initialSourceName: sources[0].name,
multiSelection: true,
const newResources = await resourceManagementProps.onChooseResource({
initialSourceName: resourceSource.name,
multiSelection: false,
resourceKind: resource.getKind(),
}).then(resources => {
if (!resources.length) return; // No path was chosen by the user.
resource.setFile(resources[0].getFile());
// Important, we are responsible for deleting the resources that were given to us.
// Otherwise we have a memory leak.
resources.forEach(resource => resource.delete());
onResourcePathUpdated();
this.forceUpdate();
});
if (!newResources.length) return; // No path was chosen by the user.
resource.setFile(newResources[0].getFile());
// Important, we are responsible for deleting the resources that were given to us.
// Otherwise we have a memory leak.
newResources.forEach(resource => resource.delete());
onResourcePathUpdated();
this.forceUpdate();
await resourceManagementProps.onFetchNewlyAddedResources();
};
_renderResourcesProperties() {

View File

@@ -13,8 +13,7 @@ import optionalRequire from '../Utils/OptionalRequire';
import Window from '../Utils/Window';
import PreferencesContext from '../MainFrame/Preferences/PreferencesContext';
import {
type ResourceSource,
type ChooseResourceFunction,
type ResourceManagementProps,
type ResourceKind,
} from '../ResourcesList/ResourceSource';
import { getResourceFilePathStatus } from '../ResourcesList/ResourceUtils';
@@ -47,8 +46,7 @@ type Props = {|
newName: string,
cb: (boolean) => void
) => void,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceManagementProps: ResourceManagementProps,
|};
const initialMosaicEditorNodes = {
@@ -207,12 +205,7 @@ export default class ResourcesEditor extends React.Component<Props, State> {
};
render() {
const {
project,
onRenameResource,
onChooseResource,
resourceSources,
} = this.props;
const { project, onRenameResource, resourceManagementProps } = this.props;
const { selectedResource } = this.state;
const editors = {
@@ -233,8 +226,7 @@ export default class ResourcesEditor extends React.Component<Props, State> {
this._resourcesList.checkMissingPaths();
}
}}
onChooseResource={onChooseResource}
resourceSources={resourceSources}
resourceManagementProps={resourceManagementProps}
/>
),
},

View File

@@ -1,30 +1,74 @@
// @flow
import { t } from '@lingui/macro';
import { t, Trans } from '@lingui/macro';
import * as React from 'react';
import {
type ChooseResourceOptions,
type ChooseResourceProps,
type ResourceSourceComponentProps,
type ResourceSource,
allResourceKindsAndMetadata,
} from './ResourceSource';
import { ResourceStore } from '../AssetStore/ResourceStore';
import { isPathInProjectFolder, copyAllToProjectFolder } from './ResourceUtils';
import optionalRequire from '../Utils/OptionalRequire';
import Window from '../Utils/Window';
import { Line } from '../UI/Grid';
import RaisedButton from '../UI/RaisedButton';
const remote = optionalRequire('@electron/remote');
const dialog = remote ? remote.dialog : null;
const path = optionalRequire('path');
type ResourceStoreChooserProps = {
options: ChooseResourceOptions,
onChooseResources: (resources: Array<gdResource>) => void,
createNewResource: () => gdResource,
};
const ResourceStoreChooser = ({
options,
onChooseResources,
createNewResource,
}: ResourceStoreChooserProps) => {
return (
<ResourceStore
onChoose={resource => {
const chosenResourceUrl = resource.url;
const newResource = createNewResource();
newResource.setFile(chosenResourceUrl);
newResource.setName(path.basename(chosenResourceUrl));
newResource.setOrigin('gdevelop-asset-store', chosenResourceUrl);
onChooseResources([newResource]);
}}
resourceKind={options.resourceKind}
/>
);
};
const localResourceSources: Array<ResourceSource> = [
...allResourceKindsAndMetadata.map(({ kind, createNewResource }) => ({
name: `resource-store-${kind}`,
displayName: t`Choose from asset store`,
displayTab: 'standalone',
kind,
renderComponent: (props: ResourceSourceComponentProps) => (
<ResourceStoreChooser
createNewResource={createNewResource}
onChooseResources={props.onChooseResources}
options={props.options}
key={`resource-store-${kind}`}
/>
),
})),
...allResourceKindsAndMetadata.map(
({ kind, displayName, fileExtensions, createNewResource }) => ({
name: 'local-file-opener-' + kind,
displayName: t`Choose a file`,
displayTab: 'import',
kind,
selectResourcesHeadless: async ({
({ kind, displayName, fileExtensions, createNewResource }) => {
const selectLocalFileResources = async ({
i18n,
getLastUsedPath,
setLastUsedPath,
project,
options,
}) => {
}: ChooseResourceProps) => {
if (!dialog)
throw new Error('Electron dialog not supported in this environment.');
@@ -72,9 +116,43 @@ const localResourceSources: Array<ResourceSource> = [
return newResource;
});
},
renderComponent: () => null,
})
};
return {
name: 'local-file-opener-' + kind,
displayName: t`Choose a file`,
displayTab: 'import',
kind,
selectResourcesHeadless: selectLocalFileResources,
renderComponent: (props: ResourceSourceComponentProps) => (
<Line justifyContent="center">
<RaisedButton
primary
label={
props.options.multiSelection ? (
<Trans>Choose one or more files</Trans>
) : (
<Trans>Choose a file</Trans>
)
}
onClick={async () => {
const resources = await selectLocalFileResources({
i18n: props.i18n,
project: props.project,
fileMetadata: props.fileMetadata,
getStorageProvider: props.getStorageProvider,
getLastUsedPath: props.getLastUsedPath,
setLastUsedPath: props.setLastUsedPath,
options: props.options,
});
props.onChooseResources(resources);
}}
/>
</Line>
),
};
}
),
];

View File

@@ -11,7 +11,7 @@ import Add from '@material-ui/icons/Add';
import Brush from '@material-ui/icons/Brush';
import {
type ResourceSource,
type ChooseResourceFunction,
type ResourceManagementProps,
type ResourceKind,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
@@ -24,9 +24,7 @@ import IconButton from '../UI/IconButton';
type Props = {|
project: gdProject,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
resourcesLoader: typeof ResourcesLoader,
resourceKind: ResourceKind,
fullWidth?: boolean,
@@ -80,7 +78,7 @@ export default class ResourceSelector extends React.Component<Props, State> {
}
_getResourceSourceItems(): DataSource {
const sources = this.props.resourceSources || [];
const sources = this.props.resourceManagementProps.resourceSources || [];
return [
...sources
.filter(source => source.kind === this.props.resourceKind)
@@ -115,42 +113,44 @@ export default class ResourceSelector extends React.Component<Props, State> {
this.autoCompleteData = [...resourceSourceItems, ...resourceItems];
}
_addFrom = (source: ResourceSource) => {
if (!source) return;
_addFrom = async (source: ResourceSource) => {
try {
if (!source) return;
const { project, onChooseResource } = this.props;
onChooseResource({
initialSourceName: source.name,
multiSelection: false,
resourceKind: this.props.resourceKind,
})
.then(resources => {
if (!resources.length) return;
const resource = resources[0];
applyResourceDefaults(project, resource);
// addResource will check if a resource with the same name exists, and if it is
// the case, no new resource will be added.
project.getResourcesManager().addResource(resource);
this._loadFrom(project.getResourcesManager());
const resourceName: string = resource.getName();
this._onChangeResourceName(resourceName);
// Imperatively set the value of the autocomplete, as it can be (on Windows for example),
// still focused. This means that when it's then getting blurred, the value we
// set for the resource name would get erased by the one that was getting entered.
if (this._autoComplete)
this._autoComplete.forceInputValueTo(resourceName);
// Important, we are responsible for deleting the resources that were given to us.
// Otherwise we have a memory leak, as calling addResource is making a copy of the resource.
resources.forEach(resource => resource.delete());
})
.catch(err => {
// Should never happen, errors should be shown in the interface.
console.error('Unable to choose a resource', err);
const { project, resourceManagementProps } = this.props;
const resources = await resourceManagementProps.onChooseResource({
initialSourceName: source.name,
multiSelection: false,
resourceKind: this.props.resourceKind,
});
if (!resources.length) return;
const resource = resources[0];
applyResourceDefaults(project, resource);
// addResource will check if a resource with the same name exists, and if it is
// the case, no new resource will be added.
project.getResourcesManager().addResource(resource);
this._loadFrom(project.getResourcesManager());
const resourceName: string = resource.getName();
this._onChangeResourceName(resourceName);
// Imperatively set the value of the autocomplete, as it can be (on Windows for example),
// still focused. This means that when it's then getting blurred, the value we
// set for the resource name would get erased by the one that was getting entered.
if (this._autoComplete)
this._autoComplete.forceInputValueTo(resourceName);
// Important, we are responsible for deleting the resources that were given to us.
// Otherwise we have a memory leak, as calling addResource is making a copy of the resource.
resources.forEach(resource => resource.delete());
await resourceManagementProps.onFetchNewlyAddedResources();
} catch (err) {
// Should never happen, errors should be shown in the interface.
console.error('Unable to choose a resource', err);
}
};
_onResetResourceName = () => {
@@ -263,7 +263,7 @@ export default class ResourceSelector extends React.Component<Props, State> {
? 'This resource does not exist in the game'
: null;
const externalEditors = this.props.resourceExternalEditors.filter(
const externalEditors = this.props.resourceManagementProps.resourceExternalEditors.filter(
externalEditor => externalEditor.kind === this.props.resourceKind
);
return (

View File

@@ -3,19 +3,15 @@ import * as React from 'react';
import ResourcesLoader from '../ResourcesLoader';
import ResourceSelector from './ResourceSelector';
import {
type ResourceSource,
type ChooseResourceFunction,
type ResourceManagementProps,
type ResourceKind,
} from './ResourceSource';
import ResourceThumbnail from './ResourceThumbnail';
import { type ResourceExternalEditor } from './ResourceExternalEditor.flow';
import { type MessageDescriptor } from '../Utils/i18n/MessageDescriptor.flow';
type Props = {|
project: gdProject,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
resourceManagementProps: ResourceManagementProps,
resourceKind: ResourceKind,
resourceName: string,
onChange: string => void,
@@ -32,9 +28,7 @@ const styles = {
const ResourceSelectorWithThumbnail = ({
project,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
resourceKind,
resourceName,
onChange,
@@ -47,9 +41,7 @@ const ResourceSelectorWithThumbnail = ({
<div style={styles.selectorContainer}>
<ResourceSelector
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={resourceManagementProps}
resourcesLoader={ResourcesLoader}
resourceKind={resourceKind}
fullWidth

View File

@@ -4,6 +4,8 @@ import { type I18n as I18nType } from '@lingui/core';
import { type MessageDescriptor } from '../Utils/i18n/MessageDescriptor.flow';
import { t } from '@lingui/macro';
import { type StorageProvider, type FileMetadata } from '../ProjectsStorage';
import { type ResourceExternalEditor } from './ResourceExternalEditor.flow';
import { type OnFetchNewlyAddedResourcesFunction } from '../ProjectsStorage/ResourceFetcher';
const gd: libGDevelop = global.gd;
@@ -95,3 +97,10 @@ export type ResourceSource = {
export type ChooseResourceFunction = (
options: ChooseResourceOptions
) => Promise<Array<gdResource>>;
export type ResourceManagementProps = {|
resourceSources: Array<ResourceSource>,
resourceExternalEditors: Array<ResourceExternalEditor>,
onChooseResource: ChooseResourceFunction,
onFetchNewlyAddedResources: OnFetchNewlyAddedResourcesFunction,
|};

View File

@@ -38,12 +38,7 @@ import { shortenString } from '../Utils/StringHelpers';
import getObjectByName from '../Utils/GetObjectByName';
import UseSceneEditorCommands from './UseSceneEditorCommands';
import { type InstancesEditorSettings } from '../InstancesEditor/InstancesEditorSettings';
import {
type ResourceSource,
type ChooseResourceFunction,
} from '../ResourcesList/ResourceSource';
import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow';
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
import {
type HistoryState,
undo,
@@ -75,7 +70,6 @@ import { type InfoBarDetails } from '../Hints/ObjectsAdditionalWork';
import { type HotReloadPreviewButtonProps } from '../HotReload/HotReloadPreviewButton';
import EventsRootVariablesFinder from '../Utils/EventsRootVariablesFinder';
import { MOVEMENT_BIG_DELTA } from '../UI/KeyboardShortcuts';
import { type OnFetchNewlyAddedResourcesFunction } from '../ProjectsStorage/ResourceFetcher';
import { getInstancesInLayoutForObject } from '../Utils/Layout';
const gd: libGDevelop = global.gd;
@@ -119,10 +113,7 @@ type Props = {|
onOpenEvents: (sceneName: string) => void,
project: gdProject,
setToolbar: (?React.Node) => void,
resourceSources: Array<ResourceSource>,
onChooseResource: ChooseResourceFunction,
resourceExternalEditors: Array<ResourceExternalEditor>,
onFetchNewlyAddedResources: OnFetchNewlyAddedResourcesFunction,
resourceManagementProps: ResourceManagementProps,
isActive: boolean,
unsavedChanges?: ?UnsavedChanges,
@@ -1228,9 +1219,7 @@ export default class SceneEditor extends React.Component<Props, State> {
project,
layout,
initialInstances,
resourceSources,
onChooseResource,
resourceExternalEditors,
resourceManagementProps,
isActive,
} = this.props;
const selectedInstances = this.instancesSelection.getSelectedInstances();
@@ -1287,9 +1276,7 @@ export default class SceneEditor extends React.Component<Props, State> {
renderEditor: () => (
<LayersList
project={project}
resourceSources={resourceSources}
resourceExternalEditors={resourceExternalEditors}
onChooseResource={onChooseResource}
resourceManagementProps={this.props.resourceManagementProps}
onEditLayerEffects={this.editLayerEffects}
onEditLayer={this.editLayer}
onRemoveLayer={this._onRemoveLayer}
@@ -1377,12 +1364,10 @@ export default class SceneEditor extends React.Component<Props, State> {
project={project}
objectsContainer={layout}
layout={layout}
resourceSources={resourceSources}
onSelectAllInstancesOfObjectInLayout={
this.onSelectAllInstancesOfObjectInLayout
}
resourceExternalEditors={resourceExternalEditors}
onChooseResource={onChooseResource}
resourceManagementProps={this.props.resourceManagementProps}
selectedObjectNames={this.state.selectedObjectNames}
onEditObject={this.props.onEditObject || this.editObject}
onDeleteObject={this._onDeleteObject(i18n)}
@@ -1406,9 +1391,6 @@ export default class SceneEditor extends React.Component<Props, State> {
hotReloadPreviewButtonProps={
this.props.hotReloadPreviewButtonProps
}
onFetchNewlyAddedResources={
this.props.onFetchNewlyAddedResources
}
/>
)}
</I18n>
@@ -1488,9 +1470,7 @@ export default class SceneEditor extends React.Component<Props, State> {
object={this.state.editedObjectWithContext.object}
initialTab={this.state.editedObjectInitialTab}
project={project}
resourceSources={resourceSources}
resourceExternalEditors={resourceExternalEditors}
onChooseResource={onChooseResource}
resourceManagementProps={resourceManagementProps}
onComputeAllVariableNames={() => {
const { editedObjectWithContext } = this.state;
if (!editedObjectWithContext) return [];
@@ -1678,9 +1658,7 @@ export default class SceneEditor extends React.Component<Props, State> {
{!!this.state.editedLayer && (
<LayerEditorDialog
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
resourceManagementProps={this.props.resourceManagementProps}
layer={this.state.editedLayer}
initialInstances={initialInstances}
initialTab={this.state.editedLayerInitialTab}

View File

@@ -29,7 +29,7 @@ type Option =
text: string, // The text used for filtering. If empty, item is always shown.
value: string, // The value to show on screen and to be selected
translatableValue?: MessageDescriptor,
onClick?: () => void, // If defined, will be called when the item is clicked. onChange/onChoose won't be called.
onClick?: () => void | Promise<void>, // If defined, will be called when the item is clicked. onChange/onChoose won't be called.
renderIcon?: ?() => React.Element<typeof ListIcon | typeof SvgIcon>,
|};

View File

@@ -24,13 +24,12 @@ export const Default = () => (
onCreateNewObject={action('onCreateNewObject')}
onObjectAddedFromAsset={action('onObjectAddedFromAsset')}
objectsContainer={testProject.testLayout}
resourceExternalEditors={fakeResourceExternalEditors}
onChooseResource={() => {
action('onChooseResource');
return Promise.reject();
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
resourceSources={[]}
onFetchNewlyAddedResources={action('onFetchNewlyAddedResources')}
/>
</AssetStoreStateProvider>
);

View File

@@ -264,9 +264,12 @@ export const WithObjectsList = () => (
project={testProject.project}
objectsContainer={testProject.testLayout}
layout={testProject.testLayout}
resourceSources={[]}
onChooseResource={() => Promise.reject('unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
onEditObject={action('On edit object')}
onAddObjectInstance={action('On add instance to the scene')}
selectedObjectNames={[]}
@@ -279,9 +282,6 @@ export const WithObjectsList = () => (
onObjectCreated={() => {}}
onObjectSelected={() => {}}
hotReloadPreviewButtonProps={hotReloadPreviewButtonProps}
onFetchNewlyAddedResources={action(
'onFetchNewlyAddedResources'
)}
/>
</TabContentContainer>
}

View File

@@ -18,12 +18,12 @@ export const withSomeEffectsForALayer = () => (
<EffectsList
target="layer"
project={testProject.project}
resourceExternalEditors={fakeResourceExternalEditors}
onChooseResource={() => {
action('onChooseResource');
return Promise.reject();
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
resourceSources={[]}
effectsContainer={testProject.layerWithEffects.getEffects()}
onEffectsUpdated={action('effects updated')}
/>
@@ -37,12 +37,12 @@ export const withSomeEffectsForAnObject = () => (
<EffectsList
target="object"
project={testProject.project}
resourceExternalEditors={fakeResourceExternalEditors}
onChooseResource={() => {
action('onChooseResource');
return Promise.reject();
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
resourceSources={[]}
effectsContainer={testProject.spriteObjectWithEffects.getEffects()}
onEffectsUpdated={action('effects updated')}
/>
@@ -56,12 +56,12 @@ export const withAnEffectWithoutEffectTypeForALayer = () => (
<EffectsList
target="layer"
project={testProject.project}
resourceExternalEditors={fakeResourceExternalEditors}
onChooseResource={() => {
action('onChooseResource');
return Promise.reject();
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
resourceSources={[]}
effectsContainer={testProject.layerWithEffectWithoutEffectType.getEffects()}
onEffectsUpdated={action('effects updated')}
/>
@@ -75,12 +75,12 @@ export const withoutEffectsForALayer = () => (
<EffectsList
target="layer"
project={testProject.project}
resourceExternalEditors={fakeResourceExternalEditors}
onChooseResource={() => {
action('onChooseResource');
return Promise.reject();
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
resourceSources={[]}
effectsContainer={testProject.layerWithoutEffects.getEffects()}
onEffectsUpdated={action('effects updated')}
/>
@@ -94,12 +94,12 @@ export const withoutEffectsForAnObject = () => (
<EffectsList
target="object"
project={testProject.project}
resourceExternalEditors={fakeResourceExternalEditors}
onChooseResource={() => {
action('onChooseResource');
return Promise.reject();
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
resourceSources={[]}
effectsContainer={testProject.spriteObjectWithoutEffects.getEffects()}
onEffectsUpdated={action('effects updated')}
/>

View File

@@ -26,11 +26,12 @@ export const DefaultNoScope = () => (
objectsContainer={testProject.testLayout}
events={testProject.testLayout.getEvents()}
onOpenExternalEvents={action('Open external events')}
resourceSources={[]}
onChooseResource={source =>
action('Choose resource from source', source)
}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
onOpenLayout={action('open layout')}
onOpenSettings={action('open settings')}
setToolbar={() => {}}
@@ -53,11 +54,12 @@ export const EmptyNoScope = () => (
objectsContainer={testProject.emptyLayout}
events={testProject.emptyLayout.getEvents()}
onOpenExternalEvents={action('Open external events')}
resourceSources={[]}
onChooseResource={source =>
action('Choose resource from source', source)
}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
onOpenLayout={action('open layout')}
onOpenSettings={action('open settings')}
setToolbar={() => {}}

View File

@@ -34,9 +34,12 @@ export const AllResourceFields = () => (
value={value}
onChange={onChange}
parameterRenderingService={ParameterRenderingService}
resourceSources={[]}
onChooseResource={() => Promise.reject('unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
/>
)}
/>
@@ -53,9 +56,12 @@ export const AllResourceFields = () => (
value={value}
onChange={onChange}
parameterRenderingService={ParameterRenderingService}
resourceSources={[]}
onChooseResource={() => Promise.reject('unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
/>
)}
/>
@@ -72,9 +78,12 @@ export const AllResourceFields = () => (
value={value}
onChange={onChange}
parameterRenderingService={ParameterRenderingService}
resourceSources={[]}
onChooseResource={() => Promise.reject('unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
/>
)}
/>
@@ -91,9 +100,12 @@ export const AllResourceFields = () => (
value={value}
onChange={onChange}
parameterRenderingService={ParameterRenderingService}
resourceSources={[]}
onChooseResource={() => Promise.reject('unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
/>
)}
/>
@@ -110,9 +122,12 @@ export const AllResourceFields = () => (
value={value}
onChange={onChange}
parameterRenderingService={ParameterRenderingService}
resourceSources={[]}
onChooseResource={() => Promise.reject('unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
/>
)}
/>
@@ -129,9 +144,12 @@ export const AllResourceFields = () => (
value={value}
onChange={onChange}
parameterRenderingService={ParameterRenderingService}
resourceSources={[]}
onChooseResource={() => Promise.reject('unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
/>
)}
/>

View File

@@ -1477,7 +1477,22 @@ storiesOf('PropertiesEditor', module)
disabled: true,
getValue: instance => 'Disabled field',
setValue: (instance, newValue) => {},
onEditButtonClick: instance => action('edit button clicked'),
},
{
name: 'Some field with edit buttons',
valueType: 'string',
getValue: instance => 'Click to test',
setValue: (instance, newValue) => {},
onEditButtonBuildMenuTemplate: () => [
{
label: 'Option 1',
click: action('Option 1'),
},
{
label: 'Option 2',
click: action('Option 2'),
},
],
},
{
name: 'Position',
@@ -1528,10 +1543,25 @@ storiesOf('PropertiesEditor', module)
disabled: true,
getValue: instance => 'Disabled field',
setValue: (instance, newValue) => {},
onEditButtonClick: instance => action('edit button clicked'),
getDescription: () =>
'This is a description. It can be fairly long and even have some *Markdown*, including [links](http://example.com).',
},
{
name: 'Some field with edit buttons',
valueType: 'string',
getValue: instance => 'Click to test',
setValue: (instance, newValue) => {},
onEditButtonBuildMenuTemplate: () => [
{
label: 'Option 1',
click: action('Option 1'),
},
{
label: 'Option 2',
click: action('Option 2'),
},
],
},
{
name: 'Position',
type: 'row',
@@ -2452,12 +2482,15 @@ storiesOf('InstructionEditor', module)
objectsContainer={testProject.testLayout}
isCondition
instruction={testProject.testInstruction}
resourceExternalEditors={fakeResourceExternalEditors}
onChooseResource={() => {
action('onChooseResource');
return Promise.reject();
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceExternalEditors: fakeResourceExternalEditors,
onChooseResource: () => {
action('onChooseResource');
return Promise.reject();
},
resourceSources: [],
}}
resourceSources={[]}
openInstructionOrExpression={action('open instruction or expression')}
/>
</FixedHeightFlexContainer>
@@ -2471,12 +2504,15 @@ storiesOf('InstructionEditor', module)
objectsContainer={testProject.testLayout}
isCondition
instruction={testProject.testInstruction}
resourceExternalEditors={fakeResourceExternalEditors}
onChooseResource={() => {
action('onChooseResource');
return Promise.reject();
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceExternalEditors: fakeResourceExternalEditors,
onChooseResource: () => {
action('onChooseResource');
return Promise.reject();
},
resourceSources: [],
}}
resourceSources={[]}
openInstructionOrExpression={action('open instruction or expression')}
/>
</FixedHeightFlexContainer>
@@ -2495,12 +2531,15 @@ storiesOf('NewInstructionEditorDialog', module)
isCondition
isNewInstruction={false}
instruction={testProject.testInstruction}
resourceExternalEditors={fakeResourceExternalEditors}
onChooseResource={() => {
action('onChooseResource');
return Promise.reject();
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceExternalEditors: fakeResourceExternalEditors,
onChooseResource: () => {
action('onChooseResource');
return Promise.reject();
},
resourceSources: [],
}}
resourceSources={[]}
openInstructionOrExpression={action('open instruction or expression')}
onCancel={action('cancel')}
onSubmit={action('submit')}
@@ -2518,12 +2557,15 @@ storiesOf('NewInstructionEditorDialog', module)
isCondition
isNewInstruction={false}
instruction={testProject.testInstruction}
resourceExternalEditors={fakeResourceExternalEditors}
onChooseResource={() => {
action('onChooseResource');
return Promise.reject();
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceExternalEditors: fakeResourceExternalEditors,
onChooseResource: () => {
action('onChooseResource');
return Promise.reject();
},
resourceSources: [],
}}
resourceSources={[]}
openInstructionOrExpression={action('open instruction or expression')}
onCancel={action('cancel')}
onSubmit={action('submit')}
@@ -2548,12 +2590,15 @@ storiesOf('NewInstructionEditorDialog', module)
isCondition
isNewInstruction={true}
instruction={testProject.testInstruction}
resourceExternalEditors={fakeResourceExternalEditors}
onChooseResource={() => {
action('onChooseResource');
return Promise.reject();
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceExternalEditors: fakeResourceExternalEditors,
onChooseResource: () => {
action('onChooseResource');
return Promise.reject();
},
resourceSources: [],
}}
resourceSources={[]}
openInstructionOrExpression={action('open instruction or expression')}
onCancel={action('cancel')}
onSubmit={action('submit')}
@@ -2585,12 +2630,12 @@ storiesOf('NewInstructionEditorMenu', module)
isCondition
isNewInstruction={false}
instruction={testProject.testInstruction}
resourceExternalEditors={fakeResourceExternalEditors}
onChooseResource={() => {
action('onChooseResource');
return Promise.reject();
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
resourceSources={[]}
openInstructionOrExpression={action(
'open instruction or expression'
)}
@@ -2613,11 +2658,12 @@ storiesOf('TextEditor', module)
<TextEditor
objectConfiguration={testProject.textObjectConfiguration}
project={testProject.project}
resourceSources={[]}
onChooseResource={source =>
action('Choose resource from source', source)
}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
onSizeUpdated={() => {}}
objectName="FakeObjectName"
/>
@@ -2634,11 +2680,12 @@ storiesOf('TiledSpriteEditor', module)
<TiledSpriteEditor
objectConfiguration={testProject.tiledSpriteObjectConfiguration}
project={testProject.project}
resourceSources={[]}
onChooseResource={source =>
action('Choose resource from source', source)
}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
onSizeUpdated={() => {}}
objectName="FakeObjectName"
/>
@@ -2655,11 +2702,12 @@ storiesOf('PanelSpriteEditor', module)
<PanelSpriteEditor
objectConfiguration={testProject.panelSpriteObjectConfiguration}
project={testProject.project}
resourceSources={[]}
onChooseResource={source =>
action('Choose resource from source', source)
}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
onSizeUpdated={() => {}}
objectName="FakeObjectName"
/>
@@ -2675,11 +2723,12 @@ storiesOf('SpriteEditor and related editors', module)
<SpriteEditor
objectConfiguration={testProject.spriteObjectConfiguration}
project={testProject.project}
resourceSources={[]}
onChooseResource={source =>
action('Choose resource from source', source)
}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
onSizeUpdated={() => {}}
objectName="FakeObjectName"
/>
@@ -2723,11 +2772,12 @@ storiesOf('ShapePainterEditor', module)
<ShapePainterEditor
objectConfiguration={testProject.shapePainterObjectConfiguration}
project={testProject.project}
resourceSources={[]}
onChooseResource={source =>
action('Choose resource from source', source)
}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
onSizeUpdated={() => {}}
objectName="FakeObjectName"
/>
@@ -2770,9 +2820,12 @@ storiesOf('ObjectsList', module)
project={testProject.project}
objectsContainer={testProject.testLayout}
layout={testProject.testLayout}
resourceSources={[]}
onChooseResource={() => Promise.reject('unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
onEditObject={action('On edit object')}
onAddObjectInstance={action('On add instance to the scene')}
onObjectCreated={action('On object created')}
@@ -2785,7 +2838,6 @@ storiesOf('ObjectsList', module)
onRenameObject={(objectWithContext, newName, cb) => cb(true)}
onObjectSelected={() => {}}
hotReloadPreviewButtonProps={hotReloadPreviewButtonProps}
onFetchNewlyAddedResources={action('onFetchNewlyAddedResources')}
/>
</div>
</SerializedObjectDisplay>
@@ -2800,9 +2852,12 @@ storiesOf('ObjectsList', module)
project={testProject.project}
objectsContainer={testProject.testLayout}
layout={testProject.testLayout}
resourceSources={[]}
onChooseResource={() => Promise.reject('unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
onEditObject={action('On edit object')}
onAddObjectInstance={action('On add instance to the scene')}
onObjectCreated={action('On object created')}
@@ -2822,7 +2877,6 @@ storiesOf('ObjectsList', module)
onRenameObject={(objectWithContext, newName, cb) => cb(true)}
onObjectSelected={() => {}}
hotReloadPreviewButtonProps={hotReloadPreviewButtonProps}
onFetchNewlyAddedResources={action('onFetchNewlyAddedResources')}
/>
</div>
</SerializedObjectDisplay>
@@ -2936,9 +2990,12 @@ storiesOf('BehaviorsEditor', module)
<BehaviorsEditor
project={testProject.project}
object={testProject.spriteObjectWithBehaviors}
resourceSources={[]}
onChooseResource={() => Promise.reject('Unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
onUpdateBehaviorsSharedData={() => {}}
/>
</SerializedObjectDisplay>
@@ -2948,9 +3005,12 @@ storiesOf('BehaviorsEditor', module)
<BehaviorsEditor
project={testProject.project}
object={testProject.spriteObjectWithoutBehaviors}
resourceSources={[]}
onChooseResource={() => Promise.reject('Unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
onUpdateBehaviorsSharedData={() => {}}
/>
</SerializedObjectDisplay>
@@ -3287,9 +3347,12 @@ storiesOf('ResourceSelector (and ResourceSelectorWithThumbnail)', module)
<ResourceSelector
resourceKind="image"
project={testProject.project}
resourceSources={[]}
onChooseResource={() => Promise.reject('Unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
initialResourceName="resource-that-does-not-exists-in-the-project"
onChange={action('on change')}
resourcesLoader={ResourcesLoader}
@@ -3299,9 +3362,12 @@ storiesOf('ResourceSelector (and ResourceSelectorWithThumbnail)', module)
<ResourceSelector
resourceKind="image"
project={testProject.project}
resourceSources={[]}
onChooseResource={() => Promise.reject('Unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
initialResourceName="icon128.png"
onChange={action('on change')}
resourcesLoader={ResourcesLoader}
@@ -3312,9 +3378,12 @@ storiesOf('ResourceSelector (and ResourceSelectorWithThumbnail)', module)
margin="none"
resourceKind="image"
project={testProject.project}
resourceSources={[]}
onChooseResource={() => Promise.reject('Unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
initialResourceName="icon128.png"
onChange={action('on change')}
resourcesLoader={ResourcesLoader}
@@ -3324,9 +3393,12 @@ storiesOf('ResourceSelector (and ResourceSelectorWithThumbnail)', module)
<ResourceSelectorWithThumbnail
resourceKind="image"
project={testProject.project}
resourceSources={[]}
onChooseResource={() => Promise.reject('Unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
resourceName="icon128.png"
onChange={action('on change')}
/>
@@ -3335,9 +3407,12 @@ storiesOf('ResourceSelector (and ResourceSelectorWithThumbnail)', module)
<ResourceSelector
resourceKind="audio"
project={testProject.project}
resourceSources={[]}
onChooseResource={() => Promise.reject('Unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
initialResourceName="fake-audio1.mp3"
onChange={action('on change')}
resourcesLoader={ResourcesLoader}
@@ -3348,9 +3423,12 @@ storiesOf('ResourceSelector (and ResourceSelectorWithThumbnail)', module)
canBeReset
resourceKind="font"
project={testProject.project}
resourceSources={[]}
onChooseResource={() => Promise.reject('Unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
initialResourceName="font.otf"
onChange={action('on change')}
resourcesLoader={ResourcesLoader}
@@ -3362,9 +3440,12 @@ storiesOf('ResourceSelector (and ResourceSelectorWithThumbnail)', module)
margin="none"
resourceKind="font"
project={testProject.project}
resourceSources={[]}
onChooseResource={() => Promise.reject('Unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
initialResourceName="font.otf"
onChange={action('on change')}
resourcesLoader={ResourcesLoader}
@@ -3475,16 +3556,16 @@ storiesOf('EventsFunctionsExtensionEditor/index', module)
project={testProject.project}
eventsFunctionsExtension={testProject.testEventsFunctionsExtension}
setToolbar={() => {}}
resourceSources={[]}
onChooseResource={source =>
action('Choose resource from source', source)
}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
openInstructionOrExpression={action('open instruction or expression')}
initiallyFocusedFunctionName={null}
initiallyFocusedBehaviorName={null}
onCreateEventsFunction={action('on create events function')}
onFetchNewlyAddedResources={action('onFetchNewlyAddedResources')}
/>
</FixedHeightFlexContainer>
</DragAndDropContextProvider>
@@ -3611,9 +3692,12 @@ storiesOf('ProjectManager', module)
)}
freezeUpdate={false}
hotReloadPreviewButtonProps={hotReloadPreviewButtonProps}
resourceSources={[]}
onChooseResource={() => Promise.reject('unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
/>
))
.add('Error in functions', () => (
@@ -3654,9 +3738,12 @@ storiesOf('ProjectManager', module)
)}
freezeUpdate={false}
hotReloadPreviewButtonProps={hotReloadPreviewButtonProps}
resourceSources={[]}
onChooseResource={() => Promise.reject('unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
/>
));
@@ -3730,12 +3817,15 @@ storiesOf('LayersList', module)
.add('default', () => (
<LayersList
project={testProject.project}
resourceExternalEditors={fakeResourceExternalEditors}
onChooseResource={() => {
action('onChooseResource');
return Promise.reject();
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceExternalEditors: fakeResourceExternalEditors,
onChooseResource: () => {
action('onChooseResource');
return Promise.reject();
},
resourceSources: [],
}}
resourceSources={[]}
onEditLayerEffects={action('onEditLayerEffects')}
onEditLayer={action('onEditLayer')}
onRemoveLayer={(layerName, cb) => {
@@ -3752,12 +3842,15 @@ storiesOf('LayersList', module)
<div style={{ width: 250, height: 200 }}>
<LayersList
project={testProject.project}
resourceExternalEditors={fakeResourceExternalEditors}
onChooseResource={() => {
action('onChooseResource');
return Promise.reject();
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceExternalEditors: fakeResourceExternalEditors,
onChooseResource: () => {
action('onChooseResource');
return Promise.reject();
},
resourceSources: [],
}}
resourceSources={[]}
onEditLayerEffects={action('onEditLayerEffects')}
onEditLayer={action('onEditLayer')}
onRemoveLayer={(layerName, cb) => {
@@ -3909,9 +4002,12 @@ storiesOf('ProjectPropertiesDialog', module)
onApply={async () => true}
onPropertiesApplied={action('onPropertiesApplied')}
onChangeSubscription={action('onChangeSubscription')}
resourceSources={[]}
onChooseResource={() => Promise.reject('unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
/>
));
@@ -3923,8 +4019,11 @@ storiesOf('ProjectPropertiesDialog/LoadingScreenEditor', module)
loadingScreen={testProject.project.getLoadingScreen()}
onChangeSubscription={action('onChangeSubscription')}
project={testProject.project}
resourceSources={[]}
onChooseResource={() => Promise.reject('unimplemented')}
resourceExternalEditors={fakeResourceExternalEditors}
resourceManagementProps={{
onFetchNewlyAddedResources: async () => {},
resourceSources: [],
onChooseResource: () => Promise.reject('Unimplemented'),
resourceExternalEditors: fakeResourceExternalEditors,
}}
/>
));