mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00

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.
197 lines
6.5 KiB
JavaScript
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>
|
|
);
|
|
}
|
|
}
|