Files
GDevelop/newIDE/app/src/EventsSheet/EventsTree/Renderers/ForEachEvent.js
Florian Rival 8adccfdaa9 Upgrade to Flow with well formed exports
Followed https://medium.com/flow-type/types-first-a-scalable-new-architecture-for-flow-3d8c7ba1d4eb.

Need to assess if this will help TypeScript conversion in the future.
2021-05-31 15:54:03 +00:00

197 lines
6.5 KiB
JavaScript

// @flow
import * as React from 'react';
import InstructionsList from '../InstructionsList.js';
import classNames from 'classnames';
import {
largeSelectedArea,
largeSelectableArea,
selectableArea,
executableEventContainer,
disabledText,
} from '../ClassNames';
import InlinePopover from '../../InlinePopover';
import ObjectField from '../../ParameterFields/ObjectField';
import { type EventRendererProps } from './EventRenderer';
import ConditionsActionsColumns from '../ConditionsActionsColumns';
import { shouldActivate } from '../../../UI/KeyboardShortcuts/InteractionKeys.js';
import { Trans } from '@lingui/macro';
const gd: libGDevelop = global.gd;
const styles = {
container: {
display: 'flex',
flexDirection: 'column',
},
instructionsContainer: {
display: 'flex',
},
actionsList: {
flex: 1,
},
};
export default class ForEachEvent extends React.Component<
EventRendererProps,
*
> {
_objectField: ?ObjectField = null;
state: {| anchorEl: null, editing: boolean |} = {
editing: false,
anchorEl: null,
};
edit: (domEvent: any) => void = (domEvent: any) => {
// We should not need to use a timeout, but
// if we don't do this, the InlinePopover's clickaway listener
// is immediately picking up the event and closing.
// Search the rest of the codebase for inlinepopover-event-hack
const anchorEl = domEvent.currentTarget;
setTimeout(
() =>
this.setState(
{
editing: true,
anchorEl,
},
() => {
// Give a bit of time for the popover to mount itself
setTimeout(() => {
if (this._objectField) this._objectField.focus();
}, 10);
}
),
10
);
};
endEditing: () => void = () => {
const { anchorEl } = this.state;
// Put back the focus after closing the inline popover.
// $FlowFixMe
if (anchorEl) anchorEl.focus();
this.setState({
editing: false,
anchorEl: null,
});
};
render(): React.Element<'div'> {
var forEachEvent = gd.asForEachEvent(this.props.event);
const objectName = forEachEvent.getObjectToPick();
return (
<div
style={styles.container}
className={classNames({
[largeSelectableArea]: true,
[largeSelectedArea]: this.props.selected,
[executableEventContainer]: true,
})}
>
<div>
<span
className={classNames({
[selectableArea]: true,
[disabledText]: this.props.disabled,
})}
onClick={this.edit}
onKeyPress={event => {
if (shouldActivate(event)) {
this.edit(event);
}
}}
tabIndex={0}
>
{objectName ? (
<Trans>Repeat for each instance of {objectName}:</Trans>
) : (
<i>
<Trans>
Click to choose for which objects this event will be repeated
</Trans>
</i>
)}
</span>
</div>
<ConditionsActionsColumns
leftIndentWidth={this.props.leftIndentWidth}
windowWidth={this.props.windowWidth}
renderConditionsList={({ style, className }) => (
<InstructionsList
instrsList={forEachEvent.getConditions()}
style={style}
className={className}
selection={this.props.selection}
areConditions
onAddNewInstruction={this.props.onAddNewInstruction}
onPasteInstructions={this.props.onPasteInstructions}
onMoveToInstruction={this.props.onMoveToInstruction}
onMoveToInstructionsList={this.props.onMoveToInstructionsList}
onInstructionClick={this.props.onInstructionClick}
onInstructionDoubleClick={this.props.onInstructionDoubleClick}
onInstructionContextMenu={this.props.onInstructionContextMenu}
onAddInstructionContextMenu={
this.props.onAddInstructionContextMenu
}
onParameterClick={this.props.onParameterClick}
disabled={this.props.disabled}
renderObjectThumbnail={this.props.renderObjectThumbnail}
screenType={this.props.screenType}
windowWidth={this.props.windowWidth}
/>
)}
renderActionsList={({ className }) => (
<InstructionsList
instrsList={forEachEvent.getActions()}
style={
{
...styles.actionsList,
} /* TODO: Use a new object to force update - somehow updates are not always propagated otherwise */
}
className={className}
selection={this.props.selection}
areConditions={false}
onAddNewInstruction={this.props.onAddNewInstruction}
onPasteInstructions={this.props.onPasteInstructions}
onMoveToInstruction={this.props.onMoveToInstruction}
onMoveToInstructionsList={this.props.onMoveToInstructionsList}
onInstructionClick={this.props.onInstructionClick}
onInstructionDoubleClick={this.props.onInstructionDoubleClick}
onInstructionContextMenu={this.props.onInstructionContextMenu}
onAddInstructionContextMenu={
this.props.onAddInstructionContextMenu
}
onParameterClick={this.props.onParameterClick}
disabled={this.props.disabled}
renderObjectThumbnail={this.props.renderObjectThumbnail}
screenType={this.props.screenType}
windowWidth={this.props.windowWidth}
/>
)}
/>
<InlinePopover
open={this.state.editing}
anchorEl={this.state.anchorEl}
onRequestClose={this.endEditing}
>
<ObjectField
project={this.props.project}
scope={this.props.scope}
globalObjectsContainer={this.props.globalObjectsContainer}
objectsContainer={this.props.objectsContainer}
value={objectName}
onChange={text => {
forEachEvent.setObjectToPick(text);
this.props.onUpdate();
}}
isInline
onRequestClose={this.endEditing}
ref={objectField => (this._objectField = objectField)}
/>
</InlinePopover>
</div>
);
}
}