mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Make the function property editor better adapt to small size (#6158)
This commit is contained in:
@@ -3,6 +3,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 Measure from 'react-measure';
|
||||
|
||||
import * as React from 'react';
|
||||
import { Column, Line, Spacer } from '../../UI/Grid';
|
||||
@@ -19,6 +20,7 @@ import DismissableAlertMessage from '../../UI/DismissableAlertMessage';
|
||||
import SemiControlledAutoComplete from '../../UI/SemiControlledAutoComplete';
|
||||
import ValueTypeEditor from './ValueTypeEditor';
|
||||
import AlertMessage from '../../UI/AlertMessage';
|
||||
import useForceUpdate from '../../Utils/UseForceUpdate';
|
||||
|
||||
const gd: libGDevelop = global.gd;
|
||||
|
||||
@@ -35,8 +37,6 @@ type Props = {|
|
||||
getFunctionGroupNames?: () => string[],
|
||||
|};
|
||||
|
||||
type State = {||};
|
||||
|
||||
export const getSentenceErrorText = (
|
||||
i18n: I18nType,
|
||||
eventsBasedBehavior: ?gdEventsBasedBehavior,
|
||||
@@ -139,371 +139,400 @@ const getDescriptionHintText = (
|
||||
return t`Example: Make the object flash for 5 seconds.`;
|
||||
};
|
||||
|
||||
export default class EventsFunctionPropertiesEditor extends React.Component<
|
||||
Props,
|
||||
State
|
||||
> {
|
||||
render() {
|
||||
const {
|
||||
project,
|
||||
eventsFunction,
|
||||
freezeEventsFunctionType,
|
||||
onConfigurationUpdated,
|
||||
helpPagePath,
|
||||
renderConfigurationHeader,
|
||||
eventsBasedBehavior,
|
||||
eventsBasedObject,
|
||||
getFunctionGroupNames,
|
||||
eventsFunctionsContainer,
|
||||
} = this.props;
|
||||
|
||||
const type = eventsFunction.getFunctionType();
|
||||
const isABehaviorLifecycleEventsFunction =
|
||||
!!eventsBasedBehavior &&
|
||||
!eventsBasedObject &&
|
||||
gd.MetadataDeclarationHelper.isBehaviorLifecycleEventsFunction(
|
||||
eventsFunction.getName()
|
||||
);
|
||||
if (isABehaviorLifecycleEventsFunction) {
|
||||
return (
|
||||
<EmptyMessage>
|
||||
<Trans>
|
||||
This is a "lifecycle method". It will be called automatically by the
|
||||
game engine for each instance living on the scene having the
|
||||
behavior.
|
||||
</Trans>
|
||||
</EmptyMessage>
|
||||
);
|
||||
}
|
||||
|
||||
const isAnObjectLifecycleEventsFunction =
|
||||
!!eventsBasedObject &&
|
||||
!eventsBasedBehavior &&
|
||||
gd.MetadataDeclarationHelper.isObjectLifecycleEventsFunction(
|
||||
eventsFunction.getName()
|
||||
);
|
||||
if (isAnObjectLifecycleEventsFunction) {
|
||||
return (
|
||||
<EmptyMessage>
|
||||
<Trans>
|
||||
This is a "lifecycle method". It will be called automatically by the
|
||||
game engine for each instance living on the scene.
|
||||
</Trans>
|
||||
</EmptyMessage>
|
||||
);
|
||||
}
|
||||
|
||||
const isAnExtensionLifecycleEventsFunction =
|
||||
!eventsBasedBehavior &&
|
||||
!eventsBasedObject &&
|
||||
gd.MetadataDeclarationHelper.isExtensionLifecycleEventsFunction(
|
||||
eventsFunction.getName()
|
||||
);
|
||||
if (isAnExtensionLifecycleEventsFunction) {
|
||||
return (
|
||||
<Column noMargin>
|
||||
<DismissableAlertMessage
|
||||
kind="info"
|
||||
identifier="lifecycle-events-function-included-only-if-extension-used"
|
||||
>
|
||||
<Trans>
|
||||
For the lifecycle functions to be executed, you need the extension
|
||||
to be used in the game, either by having at least one action,
|
||||
condition or expression used, or a behavior of the extension added
|
||||
to an object. Otherwise, the extension won't be included in the
|
||||
game.
|
||||
</Trans>
|
||||
</DismissableAlertMessage>
|
||||
<EmptyMessage>
|
||||
<Trans>
|
||||
This is a "lifecycle function". It will be called automatically by
|
||||
the game engine. It has no parameters. Only global objects can be
|
||||
used as the events will be run for all scenes in your game.
|
||||
</Trans>
|
||||
</EmptyMessage>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
const getterFunction =
|
||||
eventsFunctionsContainer &&
|
||||
type === gd.EventsFunction.ActionWithOperator &&
|
||||
eventsFunctionsContainer.hasEventsFunctionNamed(
|
||||
eventsFunction.getGetterName()
|
||||
)
|
||||
? eventsFunctionsContainer.getEventsFunction(
|
||||
eventsFunction.getGetterName()
|
||||
)
|
||||
: null;
|
||||
export const EventsFunctionPropertiesEditor = ({
|
||||
project,
|
||||
eventsFunction,
|
||||
freezeEventsFunctionType,
|
||||
onConfigurationUpdated,
|
||||
helpPagePath,
|
||||
renderConfigurationHeader,
|
||||
eventsBasedBehavior,
|
||||
eventsBasedObject,
|
||||
getFunctionGroupNames,
|
||||
eventsFunctionsContainer,
|
||||
}: Props) => {
|
||||
const forceUpdate = useForceUpdate();
|
||||
const [containerWidth, setContainerWidth] = React.useState<?number>(null);
|
||||
|
||||
const type = eventsFunction.getFunctionType();
|
||||
const isABehaviorLifecycleEventsFunction =
|
||||
!!eventsBasedBehavior &&
|
||||
!eventsBasedObject &&
|
||||
gd.MetadataDeclarationHelper.isBehaviorLifecycleEventsFunction(
|
||||
eventsFunction.getName()
|
||||
);
|
||||
if (isABehaviorLifecycleEventsFunction) {
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<ColumnStackLayout expand noMargin>
|
||||
{renderConfigurationHeader ? renderConfigurationHeader() : null}
|
||||
<ResponsiveLineStackLayout alignItems="center" noMargin>
|
||||
<Line alignItems="center" noMargin>
|
||||
<SelectField
|
||||
value={type}
|
||||
floatingLabelText={<Trans>Function type</Trans>}
|
||||
fullWidth
|
||||
disabled={!!freezeEventsFunctionType}
|
||||
onChange={(e, i, valueString: string) => {
|
||||
// $FlowFixMe
|
||||
const value: EventsFunction_FunctionType = valueString;
|
||||
eventsFunction.setFunctionType(value);
|
||||
if (onConfigurationUpdated) onConfigurationUpdated('type');
|
||||
this.forceUpdate();
|
||||
}}
|
||||
>
|
||||
<SelectOption
|
||||
value={gd.EventsFunction.Action}
|
||||
label={t`Action`}
|
||||
/>
|
||||
<SelectOption
|
||||
value={gd.EventsFunction.Condition}
|
||||
label={t`Condition`}
|
||||
/>
|
||||
<SelectOption
|
||||
value={gd.EventsFunction.Expression}
|
||||
label={t`Expression`}
|
||||
/>
|
||||
<SelectOption
|
||||
value={gd.EventsFunction.ExpressionAndCondition}
|
||||
label={t`Expression and condition`}
|
||||
/>
|
||||
<SelectOption
|
||||
value={gd.EventsFunction.ActionWithOperator}
|
||||
label={t`Action with operator`}
|
||||
/>
|
||||
</SelectField>
|
||||
</Line>
|
||||
<Column expand noMargin>
|
||||
{type === gd.EventsFunction.ActionWithOperator ? (
|
||||
<SelectField
|
||||
value={(getterFunction && getterFunction.getName()) || ''}
|
||||
floatingLabelText={
|
||||
<Trans>Related expression and condition</Trans>
|
||||
}
|
||||
fullWidth
|
||||
onChange={(e, i, value: string) => {
|
||||
eventsFunction.setGetterName(value);
|
||||
if (onConfigurationUpdated) onConfigurationUpdated();
|
||||
this.forceUpdate();
|
||||
}}
|
||||
>
|
||||
{eventsFunctionsContainer
|
||||
? mapFor(
|
||||
0,
|
||||
eventsFunctionsContainer.getEventsFunctionsCount(),
|
||||
i => {
|
||||
const eventsFunction = eventsFunctionsContainer.getEventsFunctionAt(
|
||||
i
|
||||
);
|
||||
|
||||
return (
|
||||
eventsFunction.getFunctionType() ===
|
||||
gd.EventsFunction.ExpressionAndCondition && (
|
||||
<SelectOption
|
||||
key={eventsFunction.getName()}
|
||||
value={eventsFunction.getName()}
|
||||
label={
|
||||
eventsFunction.getFullName() ||
|
||||
eventsFunction.getName()
|
||||
}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
)
|
||||
: []}
|
||||
</SelectField>
|
||||
) : (
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={
|
||||
<Trans>Full name displayed in editor</Trans>
|
||||
}
|
||||
translatableHintText={getFullNameHintText(
|
||||
type,
|
||||
eventsFunction.getExpressionType()
|
||||
)}
|
||||
value={eventsFunction.getFullName()}
|
||||
onChange={text => {
|
||||
eventsFunction.setFullName(text);
|
||||
if (onConfigurationUpdated) onConfigurationUpdated();
|
||||
this.forceUpdate();
|
||||
}}
|
||||
fullWidth
|
||||
/>
|
||||
)}
|
||||
</Column>
|
||||
<Column expand noMargin>
|
||||
{type === gd.EventsFunction.ActionWithOperator ? (
|
||||
<SemiControlledTextField
|
||||
disabled
|
||||
floatingLabelText={<Trans>Group name</Trans>}
|
||||
fullWidth
|
||||
value={getterFunction ? getterFunction.getGroup() : ''}
|
||||
onChange={text => {}}
|
||||
/>
|
||||
) : (
|
||||
<SemiControlledAutoComplete
|
||||
floatingLabelText={<Trans>Group name</Trans>}
|
||||
hintText={t`Leave it empty to use the default group for this extension.`}
|
||||
fullWidth
|
||||
value={eventsFunction.getGroup()}
|
||||
onChange={text => {
|
||||
eventsFunction.setGroup(text);
|
||||
if (onConfigurationUpdated) onConfigurationUpdated();
|
||||
this.forceUpdate();
|
||||
}}
|
||||
dataSource={
|
||||
getFunctionGroupNames
|
||||
? getFunctionGroupNames().map(name => ({
|
||||
text: name,
|
||||
value: name,
|
||||
}))
|
||||
: []
|
||||
}
|
||||
openOnFocus={true}
|
||||
/>
|
||||
)}
|
||||
</Column>
|
||||
</ResponsiveLineStackLayout>
|
||||
<Line noMargin>
|
||||
{type === gd.EventsFunction.ActionWithOperator ? (
|
||||
<SemiControlledTextField
|
||||
disabled
|
||||
commitOnBlur
|
||||
floatingLabelText={
|
||||
<Trans>Description, displayed in editor</Trans>
|
||||
}
|
||||
fullWidth
|
||||
multiline
|
||||
value={
|
||||
getterFunction
|
||||
? 'Change ' + getterFunction.getDescription()
|
||||
: ''
|
||||
}
|
||||
onChange={text => {}}
|
||||
/>
|
||||
) : (
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={
|
||||
type === gd.EventsFunction.ExpressionAndCondition ? (
|
||||
<Trans>
|
||||
Description, displayed in editor (automatically prefixed
|
||||
by "Compare" or "Return")
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>Description, displayed in editor</Trans>
|
||||
)
|
||||
}
|
||||
translatableHintText={getDescriptionHintText(
|
||||
type,
|
||||
eventsFunction.getExpressionType()
|
||||
)}
|
||||
fullWidth
|
||||
multiline
|
||||
value={eventsFunction.getDescription()}
|
||||
onChange={text => {
|
||||
eventsFunction.setDescription(text);
|
||||
if (onConfigurationUpdated) onConfigurationUpdated();
|
||||
this.forceUpdate();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Line>
|
||||
{type === gd.EventsFunction.ActionWithOperator ? (
|
||||
<Line noMargin>
|
||||
<SemiControlledTextField
|
||||
disabled
|
||||
commitOnBlur
|
||||
floatingLabelText={<Trans>Sentence in Events Sheet</Trans>}
|
||||
fullWidth
|
||||
value={
|
||||
getterFunction
|
||||
? 'Change ' +
|
||||
getterFunction.getSentence() +
|
||||
(eventsBasedBehavior || eventsBasedObject
|
||||
? ' of _PARAM0_'
|
||||
: '') +
|
||||
': [...]'
|
||||
: ''
|
||||
}
|
||||
onChange={text => {}}
|
||||
/>
|
||||
</Line>
|
||||
) : (
|
||||
(type === gd.EventsFunction.Action ||
|
||||
type === gd.EventsFunction.Condition ||
|
||||
type === gd.EventsFunction.ExpressionAndCondition) && (
|
||||
<Line noMargin>
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={
|
||||
eventsBasedBehavior &&
|
||||
type === gd.EventsFunction.ExpressionAndCondition ? (
|
||||
<Trans>
|
||||
Sentence in Events Sheet (automatically suffixed by
|
||||
"of _PARAM0_")
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>Sentence in Events Sheet</Trans>
|
||||
)
|
||||
}
|
||||
translatableHintText={t`Note: write _PARAMx_ for parameters, e.g: Flash _PARAM1_ for 5 seconds`}
|
||||
fullWidth
|
||||
value={eventsFunction.getSentence()}
|
||||
onChange={text => {
|
||||
eventsFunction.setSentence(text);
|
||||
if (onConfigurationUpdated) onConfigurationUpdated();
|
||||
this.forceUpdate();
|
||||
}}
|
||||
errorText={getSentenceErrorText(
|
||||
i18n,
|
||||
eventsBasedBehavior,
|
||||
eventsBasedObject,
|
||||
eventsFunction
|
||||
)}
|
||||
/>
|
||||
</Line>
|
||||
)
|
||||
)}
|
||||
{eventsFunction.isExpression() && (
|
||||
<ValueTypeEditor
|
||||
isExpressionType
|
||||
project={project}
|
||||
valueTypeMetadata={eventsFunction.getExpressionType()}
|
||||
isTypeSelectorShown={true}
|
||||
onTypeUpdated={() => {
|
||||
if (onConfigurationUpdated) onConfigurationUpdated();
|
||||
}}
|
||||
getLastObjectParameterObjectType={() => ''}
|
||||
/>
|
||||
)}
|
||||
{eventsFunction.isAsync() && (
|
||||
<AlertMessage kind="info">
|
||||
<Trans>
|
||||
This is an asynchronous action, meaning that the actions and
|
||||
sub-events following it will wait for it to end. Don't forget
|
||||
to use the action "End asynchronous function" to mark the end
|
||||
of the action.
|
||||
</Trans>
|
||||
</AlertMessage>
|
||||
)}
|
||||
{helpPagePath ? (
|
||||
<Line noMargin>
|
||||
<HelpButton helpPagePath={helpPagePath} />
|
||||
</Line>
|
||||
) : (
|
||||
<Spacer />
|
||||
)}
|
||||
</ColumnStackLayout>
|
||||
)}
|
||||
</I18n>
|
||||
<EmptyMessage>
|
||||
<Trans>
|
||||
This is a "lifecycle method". It will be called automatically by the
|
||||
game engine for each instance living on the scene having the behavior.
|
||||
</Trans>
|
||||
</EmptyMessage>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const isAnObjectLifecycleEventsFunction =
|
||||
!!eventsBasedObject &&
|
||||
!eventsBasedBehavior &&
|
||||
gd.MetadataDeclarationHelper.isObjectLifecycleEventsFunction(
|
||||
eventsFunction.getName()
|
||||
);
|
||||
if (isAnObjectLifecycleEventsFunction) {
|
||||
return (
|
||||
<EmptyMessage>
|
||||
<Trans>
|
||||
This is a "lifecycle method". It will be called automatically by the
|
||||
game engine for each instance living on the scene.
|
||||
</Trans>
|
||||
</EmptyMessage>
|
||||
);
|
||||
}
|
||||
|
||||
const isAnExtensionLifecycleEventsFunction =
|
||||
!eventsBasedBehavior &&
|
||||
!eventsBasedObject &&
|
||||
gd.MetadataDeclarationHelper.isExtensionLifecycleEventsFunction(
|
||||
eventsFunction.getName()
|
||||
);
|
||||
if (isAnExtensionLifecycleEventsFunction) {
|
||||
return (
|
||||
<Column noMargin>
|
||||
<DismissableAlertMessage
|
||||
kind="info"
|
||||
identifier="lifecycle-events-function-included-only-if-extension-used"
|
||||
>
|
||||
<Trans>
|
||||
For the lifecycle functions to be executed, you need the extension
|
||||
to be used in the game, either by having at least one action,
|
||||
condition or expression used, or a behavior of the extension added
|
||||
to an object. Otherwise, the extension won't be included in the
|
||||
game.
|
||||
</Trans>
|
||||
</DismissableAlertMessage>
|
||||
<EmptyMessage>
|
||||
<Trans>
|
||||
This is a "lifecycle function". It will be called automatically by
|
||||
the game engine. It has no parameters. Only global objects can be
|
||||
used as the events will be run for all scenes in your game.
|
||||
</Trans>
|
||||
</EmptyMessage>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
const getterFunction =
|
||||
eventsFunctionsContainer &&
|
||||
type === gd.EventsFunction.ActionWithOperator &&
|
||||
eventsFunctionsContainer.hasEventsFunctionNamed(
|
||||
eventsFunction.getGetterName()
|
||||
)
|
||||
? eventsFunctionsContainer.getEventsFunction(
|
||||
eventsFunction.getGetterName()
|
||||
)
|
||||
: null;
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<ColumnStackLayout expand noMargin>
|
||||
{renderConfigurationHeader ? renderConfigurationHeader() : null}
|
||||
<Measure
|
||||
bounds
|
||||
onResize={contentRect => {
|
||||
setContainerWidth(contentRect.bounds.width);
|
||||
}}
|
||||
>
|
||||
{({ contentRect, measureRef }) => (
|
||||
<div ref={measureRef}>
|
||||
<ColumnStackLayout expand noMargin>
|
||||
<ResponsiveLineStackLayout
|
||||
alignItems="center"
|
||||
noMargin
|
||||
width={
|
||||
containerWidth && containerWidth < 650
|
||||
? 'small'
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
<Line alignItems="center" noMargin>
|
||||
<SelectField
|
||||
value={type}
|
||||
floatingLabelText={<Trans>Function type</Trans>}
|
||||
fullWidth
|
||||
disabled={!!freezeEventsFunctionType}
|
||||
onChange={(e, i, valueString: string) => {
|
||||
// $FlowFixMe
|
||||
const value: EventsFunction_FunctionType = valueString;
|
||||
eventsFunction.setFunctionType(value);
|
||||
if (onConfigurationUpdated)
|
||||
onConfigurationUpdated('type');
|
||||
forceUpdate();
|
||||
}}
|
||||
>
|
||||
<SelectOption
|
||||
value={gd.EventsFunction.Action}
|
||||
label={t`Action`}
|
||||
/>
|
||||
<SelectOption
|
||||
value={gd.EventsFunction.Condition}
|
||||
label={t`Condition`}
|
||||
/>
|
||||
<SelectOption
|
||||
value={gd.EventsFunction.Expression}
|
||||
label={t`Expression`}
|
||||
/>
|
||||
<SelectOption
|
||||
value={gd.EventsFunction.ExpressionAndCondition}
|
||||
label={t`Expression and condition`}
|
||||
/>
|
||||
<SelectOption
|
||||
value={gd.EventsFunction.ActionWithOperator}
|
||||
label={t`Action with operator`}
|
||||
/>
|
||||
</SelectField>
|
||||
</Line>
|
||||
<Column expand noMargin>
|
||||
{type === gd.EventsFunction.ActionWithOperator ? (
|
||||
<SelectField
|
||||
value={
|
||||
(getterFunction && getterFunction.getName()) || ''
|
||||
}
|
||||
floatingLabelText={
|
||||
<Trans>Related expression and condition</Trans>
|
||||
}
|
||||
fullWidth
|
||||
onChange={(e, i, value: string) => {
|
||||
eventsFunction.setGetterName(value);
|
||||
if (onConfigurationUpdated)
|
||||
onConfigurationUpdated();
|
||||
forceUpdate();
|
||||
}}
|
||||
>
|
||||
{eventsFunctionsContainer
|
||||
? mapFor(
|
||||
0,
|
||||
eventsFunctionsContainer.getEventsFunctionsCount(),
|
||||
i => {
|
||||
const eventsFunction = eventsFunctionsContainer.getEventsFunctionAt(
|
||||
i
|
||||
);
|
||||
|
||||
return (
|
||||
eventsFunction.getFunctionType() ===
|
||||
gd.EventsFunction
|
||||
.ExpressionAndCondition && (
|
||||
<SelectOption
|
||||
key={eventsFunction.getName()}
|
||||
value={eventsFunction.getName()}
|
||||
label={
|
||||
eventsFunction.getFullName() ||
|
||||
eventsFunction.getName()
|
||||
}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
)
|
||||
: []}
|
||||
</SelectField>
|
||||
) : (
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={
|
||||
<Trans>Full name displayed in editor</Trans>
|
||||
}
|
||||
translatableHintText={getFullNameHintText(
|
||||
type,
|
||||
eventsFunction.getExpressionType()
|
||||
)}
|
||||
value={eventsFunction.getFullName()}
|
||||
onChange={text => {
|
||||
eventsFunction.setFullName(text);
|
||||
if (onConfigurationUpdated)
|
||||
onConfigurationUpdated();
|
||||
forceUpdate();
|
||||
}}
|
||||
fullWidth
|
||||
/>
|
||||
)}
|
||||
</Column>
|
||||
<Column expand noMargin>
|
||||
{type === gd.EventsFunction.ActionWithOperator ? (
|
||||
<SemiControlledTextField
|
||||
disabled
|
||||
floatingLabelText={<Trans>Group name</Trans>}
|
||||
fullWidth
|
||||
value={
|
||||
getterFunction ? getterFunction.getGroup() : ''
|
||||
}
|
||||
onChange={text => {}}
|
||||
/>
|
||||
) : (
|
||||
<SemiControlledAutoComplete
|
||||
floatingLabelText={<Trans>Group name</Trans>}
|
||||
hintText={t`Leave it empty to use the default group for this extension.`}
|
||||
fullWidth
|
||||
value={eventsFunction.getGroup()}
|
||||
onChange={text => {
|
||||
eventsFunction.setGroup(text);
|
||||
if (onConfigurationUpdated)
|
||||
onConfigurationUpdated();
|
||||
forceUpdate();
|
||||
}}
|
||||
dataSource={
|
||||
getFunctionGroupNames
|
||||
? getFunctionGroupNames().map(name => ({
|
||||
text: name,
|
||||
value: name,
|
||||
}))
|
||||
: []
|
||||
}
|
||||
openOnFocus={true}
|
||||
/>
|
||||
)}
|
||||
</Column>
|
||||
</ResponsiveLineStackLayout>
|
||||
<Line noMargin>
|
||||
{type === gd.EventsFunction.ActionWithOperator ? (
|
||||
<SemiControlledTextField
|
||||
disabled
|
||||
commitOnBlur
|
||||
floatingLabelText={
|
||||
<Trans>Description, displayed in editor</Trans>
|
||||
}
|
||||
fullWidth
|
||||
multiline
|
||||
value={
|
||||
getterFunction
|
||||
? 'Change ' + getterFunction.getDescription()
|
||||
: ''
|
||||
}
|
||||
onChange={text => {}}
|
||||
/>
|
||||
) : (
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={
|
||||
type === gd.EventsFunction.ExpressionAndCondition ? (
|
||||
<Trans>
|
||||
Description, displayed in editor (automatically
|
||||
prefixed by "Compare" or "Return")
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>Description, displayed in editor</Trans>
|
||||
)
|
||||
}
|
||||
translatableHintText={getDescriptionHintText(
|
||||
type,
|
||||
eventsFunction.getExpressionType()
|
||||
)}
|
||||
fullWidth
|
||||
multiline
|
||||
value={eventsFunction.getDescription()}
|
||||
onChange={text => {
|
||||
eventsFunction.setDescription(text);
|
||||
if (onConfigurationUpdated) onConfigurationUpdated();
|
||||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Line>
|
||||
{type === gd.EventsFunction.ActionWithOperator ? (
|
||||
<Line noMargin>
|
||||
<SemiControlledTextField
|
||||
disabled
|
||||
commitOnBlur
|
||||
floatingLabelText={
|
||||
<Trans>Sentence in Events Sheet</Trans>
|
||||
}
|
||||
fullWidth
|
||||
value={
|
||||
getterFunction
|
||||
? 'Change ' +
|
||||
getterFunction.getSentence() +
|
||||
(eventsBasedBehavior || eventsBasedObject
|
||||
? ' of _PARAM0_'
|
||||
: '') +
|
||||
': [...]'
|
||||
: ''
|
||||
}
|
||||
onChange={text => {}}
|
||||
/>
|
||||
</Line>
|
||||
) : (
|
||||
(type === gd.EventsFunction.Action ||
|
||||
type === gd.EventsFunction.Condition ||
|
||||
type === gd.EventsFunction.ExpressionAndCondition) && (
|
||||
<Line noMargin>
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={
|
||||
eventsBasedBehavior &&
|
||||
type ===
|
||||
gd.EventsFunction.ExpressionAndCondition ? (
|
||||
<Trans>
|
||||
Sentence in Events Sheet (automatically suffixed
|
||||
by "of _PARAM0_")
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>Sentence in Events Sheet</Trans>
|
||||
)
|
||||
}
|
||||
translatableHintText={t`Note: write _PARAMx_ for parameters, e.g: Flash _PARAM1_ for 5 seconds`}
|
||||
fullWidth
|
||||
value={eventsFunction.getSentence()}
|
||||
onChange={text => {
|
||||
eventsFunction.setSentence(text);
|
||||
if (onConfigurationUpdated)
|
||||
onConfigurationUpdated();
|
||||
forceUpdate();
|
||||
}}
|
||||
errorText={getSentenceErrorText(
|
||||
i18n,
|
||||
eventsBasedBehavior,
|
||||
eventsBasedObject,
|
||||
eventsFunction
|
||||
)}
|
||||
/>
|
||||
</Line>
|
||||
)
|
||||
)}
|
||||
{eventsFunction.isExpression() && (
|
||||
<ValueTypeEditor
|
||||
isExpressionType
|
||||
project={project}
|
||||
valueTypeMetadata={eventsFunction.getExpressionType()}
|
||||
isTypeSelectorShown={true}
|
||||
onTypeUpdated={() => {
|
||||
if (onConfigurationUpdated) onConfigurationUpdated();
|
||||
}}
|
||||
getLastObjectParameterObjectType={() => ''}
|
||||
/>
|
||||
)}
|
||||
{eventsFunction.isAsync() && (
|
||||
<AlertMessage kind="info">
|
||||
<Trans>
|
||||
This is an asynchronous action, meaning that the actions
|
||||
and sub-events following it will wait for it to end.
|
||||
Don't forget to use the action "End asynchronous
|
||||
function" to mark the end of the action.
|
||||
</Trans>
|
||||
</AlertMessage>
|
||||
)}
|
||||
{helpPagePath ? (
|
||||
<Line noMargin>
|
||||
<HelpButton helpPagePath={helpPagePath} />
|
||||
</Line>
|
||||
) : (
|
||||
<Spacer />
|
||||
)}
|
||||
</ColumnStackLayout>
|
||||
</div>
|
||||
)}
|
||||
</Measure>
|
||||
</ColumnStackLayout>
|
||||
)}
|
||||
</I18n>
|
||||
);
|
||||
};
|
||||
|
@@ -5,7 +5,7 @@ import * as React from 'react';
|
||||
import ObjectGroupsListWithObjectGroupEditor from '../../ObjectGroupsList/ObjectGroupsListWithObjectGroupEditor';
|
||||
import { Tabs } from '../../UI/Tabs';
|
||||
import { EventsFunctionParametersEditor } from './EventsFunctionParametersEditor';
|
||||
import EventsFunctionPropertiesEditor from './EventsFunctionPropertiesEditor';
|
||||
import { EventsFunctionPropertiesEditor } from './EventsFunctionPropertiesEditor';
|
||||
import ScrollView from '../../UI/ScrollView';
|
||||
import { Column, Line } from '../../UI/Grid';
|
||||
import Window from '../../Utils/Window';
|
||||
|
@@ -22,7 +22,7 @@ import {
|
||||
import AlertMessage from '../../UI/AlertMessage';
|
||||
import DismissableAlertMessage from '../../UI/DismissableAlertMessage';
|
||||
import { EventsFunctionParametersEditor } from '../../EventsFunctionsExtensionEditor/EventsFunctionConfigurationEditor/EventsFunctionParametersEditor';
|
||||
import EventsFunctionPropertiesEditor from '../../EventsFunctionsExtensionEditor/EventsFunctionConfigurationEditor/EventsFunctionPropertiesEditor';
|
||||
import { EventsFunctionPropertiesEditor } from '../../EventsFunctionsExtensionEditor/EventsFunctionConfigurationEditor/EventsFunctionPropertiesEditor';
|
||||
import HelpButton from '../../UI/HelpButton';
|
||||
import { ColumnStackLayout, ResponsiveLineStackLayout } from '../../UI/Layout';
|
||||
import { type EventsScope } from '../../InstructionOrExpression/EventsScope.flow';
|
||||
|
Reference in New Issue
Block a user