mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Improve GenericExpressionField performance
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
// @flow weak
|
||||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import TextField from 'material-ui/TextField';
|
||||
import Popover, { PopoverAnimationVertical } from 'material-ui/Popover';
|
||||
import Functions from 'material-ui/svg-icons/editor/functions';
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
import SemiControlledTextField from '../../../../UI/SemiControlledTextField';
|
||||
import ExpressionSelector from '../../InstructionOrExpressionSelector/ExpressionSelector';
|
||||
import ExpressionParametersEditorDialog from './ExpressionParametersEditorDialog';
|
||||
import ExpressionParametersEditorDialog, {
|
||||
type ParameterValues,
|
||||
} from './ExpressionParametersEditorDialog';
|
||||
import { formatExpressionCall } from './FormatExpressionCall';
|
||||
import { type InstructionOrExpressionInformation } from '../../InstructionOrExpressionSelector/InstructionOrExpressionInformation.flow.js';
|
||||
const gd = global.gd;
|
||||
@@ -44,8 +46,8 @@ type State = {|
|
||||
|};
|
||||
|
||||
export default class ExpressionField extends Component<*, State> {
|
||||
_field = null;
|
||||
_fieldElement = null;
|
||||
_field: ?any = null;
|
||||
_fieldElement: ?any = null;
|
||||
_inputElement = null;
|
||||
|
||||
state = {
|
||||
@@ -58,7 +60,7 @@ export default class ExpressionField extends Component<*, State> {
|
||||
componentDidMount() {
|
||||
if (this._field) {
|
||||
this._fieldElement = ReactDOM.findDOMNode(this._field);
|
||||
this._inputElement = this._field.getInputNode();
|
||||
this._inputElement = this._field ? this._field.getInputNode() : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,34 +74,32 @@ export default class ExpressionField extends Component<*, State> {
|
||||
});
|
||||
};
|
||||
|
||||
_handleFocus = event => {
|
||||
_handleFocus = (event: any) => {
|
||||
// This prevents ghost click.
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
_handleBlur = () => {
|
||||
this._doValidation();
|
||||
this.setState({
|
||||
popoverOpen: false,
|
||||
});
|
||||
};
|
||||
|
||||
_handleRequestClose = () => {
|
||||
this.setState({
|
||||
popoverOpen: false,
|
||||
});
|
||||
};
|
||||
|
||||
_handleChange = (e, text) => {
|
||||
if (this.props.onChange) this.props.onChange(text);
|
||||
_handleChange = (value: string) => {
|
||||
if (this.props.onChange) this.props.onChange(value);
|
||||
|
||||
this._doValidation(value);
|
||||
this.setState({
|
||||
popoverOpen: false,
|
||||
});
|
||||
};
|
||||
|
||||
_handleMenuMouseDown = event => {
|
||||
_handleMenuMouseDown = (event: any) => {
|
||||
// Keep the TextField focused
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
_handleExpressionChosen = expressionInfo => {
|
||||
_handleExpressionChosen = (expressionInfo: InstructionOrExpressionInformation) => {
|
||||
this.setState({
|
||||
popoverOpen: false,
|
||||
parametersDialogOpen: true,
|
||||
@@ -107,7 +107,10 @@ export default class ExpressionField extends Component<*, State> {
|
||||
});
|
||||
};
|
||||
|
||||
insertExpression = (expressionInfo, parameterValues) => {
|
||||
insertExpression = (
|
||||
expressionInfo: InstructionOrExpressionInformation,
|
||||
parameterValues: ParameterValues
|
||||
) => {
|
||||
if (!this._inputElement) return;
|
||||
const cursorPosition = this._inputElement.selectionStart;
|
||||
|
||||
@@ -133,14 +136,16 @@ export default class ExpressionField extends Component<*, State> {
|
||||
}, 5);
|
||||
};
|
||||
|
||||
_getError = () => {
|
||||
_getError = (value?: string) => {
|
||||
const { project, layout, expressionType } = this.props;
|
||||
|
||||
const callbacks = new gd.CallbacksForExpressionCorrectnessTesting(
|
||||
project,
|
||||
layout
|
||||
);
|
||||
const parser = new gd.ExpressionParser(this.props.value);
|
||||
const parser = new gd.ExpressionParser(
|
||||
value === undefined ? this.props.value : value
|
||||
);
|
||||
|
||||
const parseFunction =
|
||||
expressionType === 'string'
|
||||
@@ -161,8 +166,8 @@ export default class ExpressionField extends Component<*, State> {
|
||||
return isValid ? null : error;
|
||||
};
|
||||
|
||||
_doValidation = () => {
|
||||
this.setState({ errorText: this._getError() });
|
||||
_doValidation = (value?: string) => {
|
||||
this.setState({ errorText: this._getError(value) });
|
||||
};
|
||||
|
||||
render() {
|
||||
@@ -185,14 +190,14 @@ export default class ExpressionField extends Component<*, State> {
|
||||
return (
|
||||
<div style={styles.container}>
|
||||
<div style={styles.textFieldContainer}>
|
||||
<TextField
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
value={value}
|
||||
floatingLabelText={description}
|
||||
inputStyle={styles.input}
|
||||
onChange={this._handleChange}
|
||||
ref={field => (this._field = field)}
|
||||
onFocus={this._handleFocus}
|
||||
onBlur={this._handleBlur}
|
||||
errorText={this.state.errorText}
|
||||
fullWidth
|
||||
/>
|
||||
|
@@ -6,6 +6,8 @@ type State = {
|
||||
focused: boolean,
|
||||
text: ?string,
|
||||
commitOnBlur?: boolean,
|
||||
onFocus?: Function,
|
||||
onBlur?: Function,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -20,18 +22,31 @@ export default class SemiControlledTextField extends React.Component<*, State> {
|
||||
text: null,
|
||||
};
|
||||
|
||||
_field: ?any = null;
|
||||
|
||||
focus() {
|
||||
if (this._field) this._field.focus();
|
||||
}
|
||||
|
||||
getInputNode() {
|
||||
if (this._field) return this._field.getInputNode();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { value, onChange, commitOnBlur, ...otherProps } = this.props;
|
||||
const { value, onChange, commitOnBlur, onFocus, onBlur, ...otherProps } = this.props;
|
||||
|
||||
return (
|
||||
<TextField
|
||||
{...otherProps}
|
||||
ref={field => this._field = field}
|
||||
value={this.state.focused ? this.state.text : value}
|
||||
onFocus={() => {
|
||||
onFocus={(event) => {
|
||||
this.setState({
|
||||
focused: true,
|
||||
text: this.props.value,
|
||||
});
|
||||
|
||||
if (onFocus) onFocus(event);
|
||||
}}
|
||||
onChange={(event, newValue) => {
|
||||
this.setState({
|
||||
@@ -46,6 +61,8 @@ export default class SemiControlledTextField extends React.Component<*, State> {
|
||||
focused: false,
|
||||
text: null,
|
||||
});
|
||||
|
||||
if (onBlur) onBlur(event);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
Reference in New Issue
Block a user