mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
6 Commits
culling-op
...
add-prefer
Author | SHA1 | Date | |
---|---|---|---|
![]() |
06adf9070d | ||
![]() |
0747129f4f | ||
![]() |
62be7a07db | ||
![]() |
0414c58fbf | ||
![]() |
5c0c48dd05 | ||
![]() |
c8a8ef6cbc |
@@ -1,12 +1,14 @@
|
||||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import { type ParameterFieldProps } from './ParameterFieldCommons';
|
||||
import GenericExpressionField from './GenericExpressionField';
|
||||
import GenericExpressionField, {
|
||||
type ExpressionFieldInterface,
|
||||
} from './GenericExpressionField';
|
||||
import ColorPicker from '../../UI/ColorField/ColorPicker';
|
||||
import { rgbStringAndAlphaToRGBColor } from '../../Utils/ColorTransformer';
|
||||
|
||||
export default class ParameterColorField extends Component<ParameterFieldProps> {
|
||||
_field: ?GenericExpressionField;
|
||||
_field: ?ExpressionFieldInterface;
|
||||
|
||||
focus(selectAll: boolean = false) {
|
||||
if (this._field) this._field.focus(selectAll);
|
||||
|
@@ -1,13 +1,15 @@
|
||||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import GenericExpressionField from './GenericExpressionField';
|
||||
import GenericExpressionField, {
|
||||
type ExpressionFieldInterface,
|
||||
} from './GenericExpressionField';
|
||||
import { type ParameterFieldProps } from './ParameterFieldCommons';
|
||||
|
||||
export default class ExpressionField extends Component<
|
||||
ParameterFieldProps,
|
||||
void
|
||||
> {
|
||||
_field: ?GenericExpressionField;
|
||||
_field: ?ExpressionFieldInterface;
|
||||
|
||||
focus(selectAll: boolean = false) {
|
||||
if (this._field) this._field.focus(selectAll);
|
||||
|
@@ -1,6 +1,8 @@
|
||||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import GenericExpressionField from './GenericExpressionField';
|
||||
import GenericExpressionField, {
|
||||
type ExpressionFieldInterface,
|
||||
} from './GenericExpressionField';
|
||||
import { enumerateExternalLayouts } from '../../ProjectManager/EnumerateProjectItems';
|
||||
import { type ParameterFieldProps } from './ParameterFieldCommons';
|
||||
import { type ExpressionAutocompletion } from '../../ExpressionAutocompletion';
|
||||
@@ -9,7 +11,7 @@ export default class ExternalLayoutNameField extends Component<
|
||||
ParameterFieldProps,
|
||||
void
|
||||
> {
|
||||
_field: ?GenericExpressionField;
|
||||
_field: ?ExpressionFieldInterface;
|
||||
|
||||
focus(selectAll: boolean = false) {
|
||||
if (this._field) this._field.focus(selectAll);
|
||||
|
@@ -1,6 +1,8 @@
|
||||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import GenericExpressionField from './GenericExpressionField';
|
||||
import GenericExpressionField, {
|
||||
type ExpressionFieldInterface,
|
||||
} from './GenericExpressionField';
|
||||
import { type ParameterFieldProps } from './ParameterFieldCommons';
|
||||
import { type ExpressionAutocompletion } from '../../ExpressionAutocompletion';
|
||||
import { enumerateParametersUsableInExpressions } from './EnumerateFunctionParameters';
|
||||
@@ -9,7 +11,7 @@ export default class FunctionParameterNameField extends Component<
|
||||
ParameterFieldProps,
|
||||
void
|
||||
> {
|
||||
_field: ?GenericExpressionField;
|
||||
_field: ?ExpressionFieldInterface;
|
||||
|
||||
focus(selectAll: boolean = false) {
|
||||
if (this._field) this._field.focus(selectAll);
|
||||
|
@@ -117,3 +117,5 @@ export const formatExpressionCall = (
|
||||
return `${functionName}(${functionArgs})`;
|
||||
}
|
||||
};
|
||||
|
||||
// export const wrapExpressionCallWithTypeChange = ()
|
||||
|
@@ -42,6 +42,7 @@ import {
|
||||
shouldCloseOrCancel,
|
||||
shouldSubmit,
|
||||
} from '../../../UI/KeyboardShortcuts/InteractionKeys';
|
||||
import PreferencesContext from '../../../MainFrame/Preferences/PreferencesContext';
|
||||
const gd: libGDevelop = global.gd;
|
||||
|
||||
const styles = {
|
||||
@@ -163,7 +164,10 @@ const extractErrors = (
|
||||
return { errorText, errorHighlights };
|
||||
};
|
||||
|
||||
export default class ExpressionField extends React.Component<Props, State> {
|
||||
class ExpressionField extends React.Component<
|
||||
{| ...Props, useAllExpressionTypes: boolean |},
|
||||
State
|
||||
> {
|
||||
_field: ?SemiControlledTextField = null;
|
||||
_fieldElement: ?Element = null;
|
||||
_inputElement: ?HTMLInputElement = null;
|
||||
@@ -371,6 +375,7 @@ export default class ExpressionField extends React.Component<Props, State> {
|
||||
scope,
|
||||
onGetAdditionalAutocompletions,
|
||||
onExtractAdditionalErrors,
|
||||
useAllExpressionTypes,
|
||||
} = this.props;
|
||||
if (!project) return null;
|
||||
|
||||
@@ -430,7 +435,8 @@ export default class ExpressionField extends React.Component<Props, State> {
|
||||
objectsContainer,
|
||||
scope,
|
||||
},
|
||||
completionDescriptions
|
||||
completionDescriptions,
|
||||
useAllExpressionTypes
|
||||
);
|
||||
const allNewAutocompletions = onGetAdditionalAutocompletions
|
||||
? onGetAdditionalAutocompletions(expression).concat(newAutocompletions)
|
||||
@@ -566,7 +572,11 @@ export default class ExpressionField extends React.Component<Props, State> {
|
||||
onChoose={(type, expression) => {
|
||||
this._handleExpressionChosen(expression);
|
||||
}}
|
||||
expressionType={expressionType}
|
||||
expressionType={
|
||||
this.props.useAllExpressionTypes
|
||||
? 'number|string'
|
||||
: expressionType
|
||||
}
|
||||
focusOnMount
|
||||
scope={scope}
|
||||
/>
|
||||
@@ -663,3 +673,35 @@ export default class ExpressionField extends React.Component<Props, State> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export type ExpressionFieldInterface = {|
|
||||
focus: (selectAll?: boolean) => void,
|
||||
|};
|
||||
|
||||
// GenericExpressionField is a wrapper so that the component can use multiple
|
||||
// context in class methods while correctly exposing the interface.
|
||||
const GenericExpressionField = (props, ref) => {
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
focus,
|
||||
}));
|
||||
|
||||
const component = React.useRef<?ExpressionField>(null);
|
||||
const focus = (selectAll?: boolean) => {
|
||||
if (component.current) component.current.focus(selectAll);
|
||||
};
|
||||
|
||||
const {
|
||||
values: { eventsSheetUseAllExpressionTypes },
|
||||
} = React.useContext(PreferencesContext);
|
||||
return (
|
||||
<ExpressionField
|
||||
ref={component}
|
||||
useAllExpressionTypes={eventsSheetUseAllExpressionTypes}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.forwardRef<Props, ExpressionFieldInterface>(
|
||||
GenericExpressionField
|
||||
);
|
||||
|
@@ -1,6 +1,8 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import GenericExpressionField from './GenericExpressionField';
|
||||
import GenericExpressionField, {
|
||||
type ExpressionFieldInterface,
|
||||
} from './GenericExpressionField';
|
||||
import {
|
||||
type ParameterFieldProps,
|
||||
type ParameterFieldInterface,
|
||||
@@ -14,7 +16,7 @@ import { enumerateEffectNames } from '../../EffectsList/EnumerateEffects';
|
||||
|
||||
export default React.forwardRef<ParameterFieldProps, ParameterFieldInterface>(
|
||||
function LayerEffectNameField(props: ParameterFieldProps, ref) {
|
||||
const field = React.useRef<?GenericExpressionField>(null);
|
||||
const field = React.useRef<?ExpressionFieldInterface>(null);
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
focus: (selectAll: boolean = false) => {
|
||||
if (field.current) field.current.focus(selectAll);
|
||||
|
@@ -1,6 +1,8 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import GenericExpressionField from './GenericExpressionField';
|
||||
import GenericExpressionField, {
|
||||
type ExpressionFieldInterface,
|
||||
} from './GenericExpressionField';
|
||||
import {
|
||||
type ParameterFieldProps,
|
||||
type ParameterFieldInterface,
|
||||
@@ -15,7 +17,7 @@ const gd: libGDevelop = global.gd;
|
||||
|
||||
export default React.forwardRef<ParameterFieldProps, ParameterFieldInterface>(
|
||||
function LayerEffectParameterNameField(props: ParameterFieldProps, ref) {
|
||||
const field = React.useRef<?GenericExpressionField>(null);
|
||||
const field = React.useRef<?ExpressionFieldInterface>(null);
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
focus: (selectAll: boolean = false) => {
|
||||
if (field.current) field.current.focus(selectAll);
|
||||
|
@@ -2,11 +2,13 @@
|
||||
import React, { Component } from 'react';
|
||||
import { mapFor } from '../../Utils/MapFor';
|
||||
import { type ParameterFieldProps } from './ParameterFieldCommons';
|
||||
import GenericExpressionField from './GenericExpressionField';
|
||||
import GenericExpressionField, {
|
||||
type ExpressionFieldInterface,
|
||||
} from './GenericExpressionField';
|
||||
import { type ExpressionAutocompletion } from '../../ExpressionAutocompletion';
|
||||
|
||||
export default class LayerField extends Component<ParameterFieldProps, {||}> {
|
||||
_field: ?GenericExpressionField;
|
||||
_field: ?ExpressionFieldInterface;
|
||||
|
||||
focus(selectAll: boolean = false) {
|
||||
if (this._field) this._field.focus(selectAll);
|
||||
|
@@ -15,7 +15,9 @@ import RaisedButtonWithSplitMenu from '../../UI/RaisedButtonWithSplitMenu';
|
||||
import { type Leaderboard } from '../../Utils/GDevelopServices/Play';
|
||||
import LeaderboardContext from '../../Leaderboard/LeaderboardContext';
|
||||
import LeaderboardDialog from '../../Leaderboard/LeaderboardDialog';
|
||||
import GenericExpressionField from './GenericExpressionField';
|
||||
import GenericExpressionField, {
|
||||
type ExpressionFieldInterface,
|
||||
} from './GenericExpressionField';
|
||||
import { breakUuid } from '../../Utils/GDevelopServices/Play';
|
||||
import { useOnlineStatus } from '../../Utils/OnlineStatus';
|
||||
|
||||
@@ -58,7 +60,7 @@ export default React.forwardRef<ParameterFieldProps, ParameterFieldInterface>(
|
||||
const leaderboards = useFetchLeaderboards();
|
||||
const [isAdminOpen, setIsAdminOpen] = React.useState(false);
|
||||
const inputFieldRef = React.useRef<?(
|
||||
| GenericExpressionField
|
||||
| ExpressionFieldInterface
|
||||
| SelectFieldInterface
|
||||
)>(null);
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
|
@@ -1,6 +1,8 @@
|
||||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import GenericExpressionField from './GenericExpressionField';
|
||||
import GenericExpressionField, {
|
||||
type ExpressionFieldInterface,
|
||||
} from './GenericExpressionField';
|
||||
import { type ParameterFieldProps } from './ParameterFieldCommons';
|
||||
import { type ExpressionAutocompletion } from '../../ExpressionAutocompletion';
|
||||
import getObjectByName from '../../Utils/GetObjectByName';
|
||||
@@ -13,7 +15,7 @@ export default class ObjectAnimationNameField extends Component<
|
||||
ParameterFieldProps,
|
||||
void
|
||||
> {
|
||||
_field: ?GenericExpressionField;
|
||||
_field: ?ExpressionFieldInterface;
|
||||
|
||||
focus(selectAll: boolean = false) {
|
||||
if (this._field) this._field.focus(selectAll);
|
||||
|
@@ -1,6 +1,8 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import GenericExpressionField from './GenericExpressionField';
|
||||
import GenericExpressionField, {
|
||||
type ExpressionFieldInterface,
|
||||
} from './GenericExpressionField';
|
||||
import {
|
||||
type ParameterFieldProps,
|
||||
type ParameterFieldInterface,
|
||||
@@ -12,7 +14,7 @@ import { enumerateEffectNames } from '../../EffectsList/EnumerateEffects';
|
||||
|
||||
export default React.forwardRef<ParameterFieldProps, ParameterFieldInterface>(
|
||||
function ObjectEffectNameField(props: ParameterFieldProps, ref) {
|
||||
const field = React.useRef<?GenericExpressionField>(null);
|
||||
const field = React.useRef<?ExpressionFieldInterface>(null);
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
focus: (selectAll: boolean = false) => {
|
||||
if (field.current) field.current.focus(selectAll);
|
||||
|
@@ -1,6 +1,8 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import GenericExpressionField from './GenericExpressionField';
|
||||
import GenericExpressionField, {
|
||||
type ExpressionFieldInterface,
|
||||
} from './GenericExpressionField';
|
||||
import {
|
||||
type ParameterFieldProps,
|
||||
type ParameterFieldInterface,
|
||||
@@ -17,7 +19,7 @@ const gd: libGDevelop = global.gd;
|
||||
|
||||
export default React.forwardRef<ParameterFieldProps, ParameterFieldInterface>(
|
||||
function ObjectEffectParameterNameField(props: ParameterFieldProps, ref) {
|
||||
const field = React.useRef<?GenericExpressionField>(null);
|
||||
const field = React.useRef<?ExpressionFieldInterface>(null);
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
focus: (selectAll: boolean = false) => {
|
||||
if (field.current) field.current.focus(selectAll);
|
||||
|
@@ -1,6 +1,8 @@
|
||||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import GenericExpressionField from './GenericExpressionField';
|
||||
import GenericExpressionField, {
|
||||
type ExpressionFieldInterface,
|
||||
} from './GenericExpressionField';
|
||||
import { type ParameterFieldProps } from './ParameterFieldCommons';
|
||||
import { type ExpressionAutocompletion } from '../../ExpressionAutocompletion';
|
||||
import getObjectByName from '../../Utils/GetObjectByName';
|
||||
@@ -13,7 +15,7 @@ export default class ObjectPointNameField extends Component<
|
||||
ParameterFieldProps,
|
||||
void
|
||||
> {
|
||||
_field: ?GenericExpressionField;
|
||||
_field: ?ExpressionFieldInterface;
|
||||
|
||||
focus(selectAll: boolean = false) {
|
||||
if (this._field) this._field.focus(selectAll);
|
||||
|
@@ -1,6 +1,8 @@
|
||||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import GenericExpressionField from './GenericExpressionField';
|
||||
import GenericExpressionField, {
|
||||
type ExpressionFieldInterface,
|
||||
} from './GenericExpressionField';
|
||||
import { enumerateLayouts } from '../../ProjectManager/EnumerateProjectItems';
|
||||
import { type ParameterFieldProps } from './ParameterFieldCommons';
|
||||
import { type ExpressionAutocompletion } from '../../ExpressionAutocompletion';
|
||||
@@ -9,7 +11,7 @@ export default class SceneNameField extends Component<
|
||||
ParameterFieldProps,
|
||||
void
|
||||
> {
|
||||
_field: ?GenericExpressionField;
|
||||
_field: ?ExpressionFieldInterface;
|
||||
|
||||
focus(selectAll: boolean = false) {
|
||||
if (this._field) this._field.focus(selectAll);
|
||||
|
@@ -1,10 +1,12 @@
|
||||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import GenericExpressionField from './GenericExpressionField';
|
||||
import GenericExpressionField, {
|
||||
type ExpressionFieldInterface,
|
||||
} from './GenericExpressionField';
|
||||
import { type ParameterFieldProps } from './ParameterFieldCommons';
|
||||
|
||||
export default class StringField extends Component<ParameterFieldProps, void> {
|
||||
_field: ?GenericExpressionField;
|
||||
_field: ?ExpressionFieldInterface;
|
||||
|
||||
focus(selectAll: boolean = false) {
|
||||
if (this._field) this._field.focus(selectAll);
|
||||
|
@@ -1,6 +1,8 @@
|
||||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import GenericExpressionField from './GenericExpressionField';
|
||||
import GenericExpressionField, {
|
||||
type ExpressionFieldInterface,
|
||||
} from './GenericExpressionField';
|
||||
import { type ParameterFieldProps } from './ParameterFieldCommons';
|
||||
import { getParameterChoices } from './ParameterMetadataTools';
|
||||
|
||||
@@ -8,7 +10,7 @@ export default class StringWithSelectorField extends Component<
|
||||
ParameterFieldProps,
|
||||
{||}
|
||||
> {
|
||||
_field: ?GenericExpressionField;
|
||||
_field: ?ExpressionFieldInterface;
|
||||
|
||||
focus(selectAll: boolean = false) {
|
||||
if (this._field) this._field.focus(selectAll);
|
||||
|
@@ -78,7 +78,8 @@ describe('ExpressionAutocompletion', () => {
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptions
|
||||
completionDescriptions,
|
||||
false
|
||||
);
|
||||
expect(autocompletions).toHaveLength(2);
|
||||
expect(autocompletions).toEqual(
|
||||
@@ -113,7 +114,8 @@ describe('ExpressionAutocompletion', () => {
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptions2
|
||||
completionDescriptions2,
|
||||
false
|
||||
);
|
||||
expect(autocompletions2).toHaveLength(1);
|
||||
expect(autocompletions2).toEqual(
|
||||
@@ -125,6 +127,36 @@ describe('ExpressionAutocompletion', () => {
|
||||
}),
|
||||
])
|
||||
);
|
||||
|
||||
const completionDescriptionsWithAllTypes = gd.ExpressionCompletionFinder.getCompletionDescriptionsFor(
|
||||
gd.JsPlatform.get(),
|
||||
project,
|
||||
testLayout,
|
||||
'number',
|
||||
expressionNode2,
|
||||
1
|
||||
);
|
||||
const autocompletionsWithAllTypes = getAutocompletionsFromDescriptions(
|
||||
{
|
||||
gd,
|
||||
project: project,
|
||||
globalObjectsContainer: project,
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptionsWithAllTypes,
|
||||
true
|
||||
);
|
||||
expect(autocompletionsWithAllTypes).toHaveLength(1);
|
||||
expect(autocompletionsWithAllTypes).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
completion: 'MySpriteObjectWithBehaviors',
|
||||
addDot: true,
|
||||
kind: 'Object',
|
||||
}),
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
it('can autocomplete free expressions', () => {
|
||||
@@ -148,7 +180,8 @@ describe('ExpressionAutocompletion', () => {
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptions
|
||||
completionDescriptions,
|
||||
false
|
||||
);
|
||||
expect(autocompletions).toEqual(
|
||||
expect.arrayContaining([
|
||||
@@ -169,6 +202,59 @@ describe('ExpressionAutocompletion', () => {
|
||||
}),
|
||||
])
|
||||
);
|
||||
expect(autocompletions).not.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
completion: 'ToString',
|
||||
addParenthesis: true,
|
||||
isExact: false,
|
||||
}),
|
||||
])
|
||||
);
|
||||
|
||||
const completionDescriptionsWithAllTypes = gd.ExpressionCompletionFinder.getCompletionDescriptionsFor(
|
||||
gd.JsPlatform.get(),
|
||||
project,
|
||||
testLayout,
|
||||
'number',
|
||||
expressionNode,
|
||||
1
|
||||
);
|
||||
const autocompletionsWithAllTypes = getAutocompletionsFromDescriptions(
|
||||
{
|
||||
gd,
|
||||
project: project,
|
||||
globalObjectsContainer: project,
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptionsWithAllTypes,
|
||||
true
|
||||
);
|
||||
expect(autocompletionsWithAllTypes).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
completion: 'ToDeg',
|
||||
addParenthesis: true,
|
||||
isExact: false,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
completion: 'ToRad',
|
||||
addParenthesis: true,
|
||||
isExact: false,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
completion: 'TouchX',
|
||||
addParenthesis: true,
|
||||
isExact: false,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
completion: 'ToString',
|
||||
addParenthesis: true,
|
||||
isExact: false,
|
||||
}),
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
it('can autocomplete layer parameters', () => {
|
||||
@@ -192,7 +278,8 @@ describe('ExpressionAutocompletion', () => {
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptions
|
||||
completionDescriptions,
|
||||
false
|
||||
);
|
||||
expect(autocompletions).toEqual(
|
||||
expect.arrayContaining([
|
||||
@@ -202,13 +289,41 @@ describe('ExpressionAutocompletion', () => {
|
||||
}),
|
||||
])
|
||||
);
|
||||
|
||||
const completionDescriptionsWithAllTypes = gd.ExpressionCompletionFinder.getCompletionDescriptionsFor(
|
||||
gd.JsPlatform.get(),
|
||||
project,
|
||||
testLayout,
|
||||
'number',
|
||||
expressionNode,
|
||||
9
|
||||
);
|
||||
const autocompletionsWithAllTypes = getAutocompletionsFromDescriptions(
|
||||
{
|
||||
gd,
|
||||
project: project,
|
||||
globalObjectsContainer: project,
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptionsWithAllTypes,
|
||||
true
|
||||
);
|
||||
expect(autocompletionsWithAllTypes).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
completion: '"Background"',
|
||||
addParameterSeparator: true,
|
||||
}),
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
it('can autocomplete object expressions', () => {
|
||||
const { project, testLayout, parser } = makeTestContext();
|
||||
const scope = { layout: testLayout };
|
||||
|
||||
const expressionNode = parser.parseExpression('MySpriteObject.Po').get();
|
||||
const expressionNode = parser.parseExpression('MySpriteObject.Ani').get();
|
||||
const completionDescriptions = gd.ExpressionCompletionFinder.getCompletionDescriptionsFor(
|
||||
gd.JsPlatform.get(),
|
||||
project,
|
||||
@@ -225,17 +340,66 @@ describe('ExpressionAutocompletion', () => {
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptions
|
||||
completionDescriptions,
|
||||
false
|
||||
);
|
||||
expect(autocompletions).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
completion: 'PointX',
|
||||
completion: 'Animation',
|
||||
addParenthesis: true,
|
||||
isExact: false,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
completion: 'PointY',
|
||||
completion: 'AnimationSpeedScale',
|
||||
addParenthesis: true,
|
||||
isExact: false,
|
||||
}),
|
||||
])
|
||||
);
|
||||
expect(autocompletions).not.toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
completion: 'AnimationName',
|
||||
addParenthesis: true,
|
||||
isExact: false,
|
||||
}),
|
||||
])
|
||||
);
|
||||
|
||||
const completionDescriptionsWithAllTypes = gd.ExpressionCompletionFinder.getCompletionDescriptionsFor(
|
||||
gd.JsPlatform.get(),
|
||||
project,
|
||||
testLayout,
|
||||
'number',
|
||||
expressionNode,
|
||||
16
|
||||
);
|
||||
const autocompletionsWithAllTypes = getAutocompletionsFromDescriptions(
|
||||
{
|
||||
gd,
|
||||
project: project,
|
||||
globalObjectsContainer: project,
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptionsWithAllTypes,
|
||||
true
|
||||
);
|
||||
expect(autocompletionsWithAllTypes).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
completion: 'Animation',
|
||||
addParenthesis: true,
|
||||
isExact: false,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
completion: 'AnimationSpeedScale',
|
||||
addParenthesis: true,
|
||||
isExact: false,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
completion: 'AnimationName',
|
||||
addParenthesis: true,
|
||||
isExact: false,
|
||||
}),
|
||||
@@ -266,7 +430,8 @@ describe('ExpressionAutocompletion', () => {
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptions
|
||||
completionDescriptions,
|
||||
false
|
||||
);
|
||||
expect(autocompletions).toEqual(
|
||||
expect.arrayContaining([
|
||||
@@ -276,6 +441,34 @@ describe('ExpressionAutocompletion', () => {
|
||||
}),
|
||||
])
|
||||
);
|
||||
|
||||
const completionDescriptionsWithAllTypes = gd.ExpressionCompletionFinder.getCompletionDescriptionsFor(
|
||||
gd.JsPlatform.get(),
|
||||
project,
|
||||
testLayout,
|
||||
'number',
|
||||
expressionNode,
|
||||
24
|
||||
);
|
||||
const autocompletionsWithAllTypes = getAutocompletionsFromDescriptions(
|
||||
{
|
||||
gd,
|
||||
project: project,
|
||||
globalObjectsContainer: project,
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptionsWithAllTypes,
|
||||
true
|
||||
);
|
||||
expect(autocompletionsWithAllTypes).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
completion: '"Head"',
|
||||
addParameterSeparator: false,
|
||||
}),
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
it('can autocomplete behaviors (1)', () => {
|
||||
@@ -301,7 +494,8 @@ describe('ExpressionAutocompletion', () => {
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptions
|
||||
completionDescriptions,
|
||||
false
|
||||
);
|
||||
expect(autocompletions).toEqual(
|
||||
expect.arrayContaining([
|
||||
@@ -312,6 +506,35 @@ describe('ExpressionAutocompletion', () => {
|
||||
}),
|
||||
])
|
||||
);
|
||||
|
||||
const completionDescriptionsWithAllTypes = gd.ExpressionCompletionFinder.getCompletionDescriptionsFor(
|
||||
gd.JsPlatform.get(),
|
||||
project,
|
||||
testLayout,
|
||||
'number',
|
||||
expressionNode,
|
||||
28
|
||||
);
|
||||
const autocompletionsWithAllTypes = getAutocompletionsFromDescriptions(
|
||||
{
|
||||
gd,
|
||||
project: project,
|
||||
globalObjectsContainer: project,
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptionsWithAllTypes,
|
||||
true
|
||||
);
|
||||
expect(autocompletionsWithAllTypes).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
completion: 'PlatformerObject',
|
||||
addNamespaceSeparator: true,
|
||||
isExact: false,
|
||||
}),
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
it('can autocomplete behaviors (2)', () => {
|
||||
@@ -337,7 +560,8 @@ describe('ExpressionAutocompletion', () => {
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptions
|
||||
completionDescriptions,
|
||||
false
|
||||
);
|
||||
expect(autocompletions).toEqual(
|
||||
expect.arrayContaining([
|
||||
@@ -353,6 +577,40 @@ describe('ExpressionAutocompletion', () => {
|
||||
}),
|
||||
])
|
||||
);
|
||||
|
||||
const completionDescriptionsWithAllTypes = gd.ExpressionCompletionFinder.getCompletionDescriptionsFor(
|
||||
gd.JsPlatform.get(),
|
||||
project,
|
||||
testLayout,
|
||||
'number',
|
||||
expressionNode,
|
||||
28
|
||||
);
|
||||
const autocompletionsWithAllTypes = getAutocompletionsFromDescriptions(
|
||||
{
|
||||
gd,
|
||||
project: project,
|
||||
globalObjectsContainer: project,
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptionsWithAllTypes,
|
||||
true
|
||||
);
|
||||
expect(autocompletionsWithAllTypes).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
completion: 'PlatformerObject',
|
||||
addNamespaceSeparator: true,
|
||||
isExact: false,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
completion: 'PlatformerObject',
|
||||
addNamespaceSeparator: true,
|
||||
isExact: false,
|
||||
}),
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
it('can autocomplete behavior expressions', () => {
|
||||
@@ -378,7 +636,8 @@ describe('ExpressionAutocompletion', () => {
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptions
|
||||
completionDescriptions,
|
||||
false
|
||||
);
|
||||
expect(autocompletions).toEqual(
|
||||
expect.arrayContaining([
|
||||
@@ -389,6 +648,35 @@ describe('ExpressionAutocompletion', () => {
|
||||
}),
|
||||
])
|
||||
);
|
||||
|
||||
const completionDescriptionsWithAllTypes = gd.ExpressionCompletionFinder.getCompletionDescriptionsFor(
|
||||
gd.JsPlatform.get(),
|
||||
project,
|
||||
testLayout,
|
||||
'string',
|
||||
expressionNode,
|
||||
47
|
||||
);
|
||||
const autocompletionsWithAllTypes = getAutocompletionsFromDescriptions(
|
||||
{
|
||||
gd,
|
||||
project: project,
|
||||
globalObjectsContainer: project,
|
||||
objectsContainer: testLayout,
|
||||
scope,
|
||||
},
|
||||
completionDescriptionsWithAllTypes,
|
||||
true
|
||||
);
|
||||
expect(autocompletionsWithAllTypes).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
completion: 'JumpSpeed',
|
||||
addParenthesis: true,
|
||||
isExact: false,
|
||||
}),
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
it('can insert autocompletion', () => {
|
||||
|
@@ -120,10 +120,13 @@ const getAutocompletionsForExpressions = (
|
||||
|
||||
const getAutocompletionsForFreeExpressions = function(
|
||||
expressionAutocompletionContext: ExpressionAutocompletionContext,
|
||||
completionDescription: gdExpressionCompletionDescription
|
||||
completionDescription: gdExpressionCompletionDescription,
|
||||
useAllExpressionTypes: boolean
|
||||
): Array<ExpressionAutocompletion> {
|
||||
const prefix: string = completionDescription.getPrefix();
|
||||
const type: string = completionDescription.getType();
|
||||
const type: string = useAllExpressionTypes
|
||||
? 'number|string'
|
||||
: completionDescription.getType();
|
||||
const isExact: boolean = completionDescription.isExact();
|
||||
|
||||
const freeExpressions = enumerateFreeExpressions(type);
|
||||
@@ -143,10 +146,13 @@ const getAutocompletionsForFreeExpressions = function(
|
||||
|
||||
const getAutocompletionsForObjectExpressions = function(
|
||||
expressionAutocompletionContext: ExpressionAutocompletionContext,
|
||||
completionDescription: gdExpressionCompletionDescription
|
||||
completionDescription: gdExpressionCompletionDescription,
|
||||
useAllExpressionTypes: boolean
|
||||
): Array<ExpressionAutocompletion> {
|
||||
const prefix: string = completionDescription.getPrefix();
|
||||
const type: string = completionDescription.getType();
|
||||
const type: string = useAllExpressionTypes
|
||||
? 'number|string'
|
||||
: completionDescription.getType();
|
||||
const objectName: string = completionDescription.getObjectName();
|
||||
const isExact: boolean = completionDescription.isExact();
|
||||
const {
|
||||
@@ -178,10 +184,13 @@ const getAutocompletionsForObjectExpressions = function(
|
||||
|
||||
const getAutocompletionsForBehaviorExpressions = function(
|
||||
expressionAutocompletionContext: ExpressionAutocompletionContext,
|
||||
completionDescription: gdExpressionCompletionDescription
|
||||
completionDescription: gdExpressionCompletionDescription,
|
||||
useAllExpressionTypes: boolean
|
||||
): Array<ExpressionAutocompletion> {
|
||||
const prefix: string = completionDescription.getPrefix();
|
||||
const type: string = completionDescription.getType();
|
||||
const type: string = useAllExpressionTypes
|
||||
? 'number|string'
|
||||
: completionDescription.getType();
|
||||
const behaviorName: string = completionDescription.getBehaviorName();
|
||||
const isExact: boolean = completionDescription.isExact();
|
||||
const {
|
||||
@@ -445,7 +454,8 @@ const getAutocompletionsForBehavior = function(
|
||||
|
||||
export const getAutocompletionsFromDescriptions = (
|
||||
expressionAutocompletionContext: ExpressionAutocompletionContext,
|
||||
expressionCompletionDescriptions: gdVectorExpressionCompletionDescription
|
||||
expressionCompletionDescriptions: gdVectorExpressionCompletionDescription,
|
||||
useAllExpressionTypes: boolean
|
||||
): Array<ExpressionAutocompletion> => {
|
||||
const { gd } = expressionAutocompletionContext;
|
||||
|
||||
@@ -460,17 +470,20 @@ export const getAutocompletionsFromDescriptions = (
|
||||
if (behaviorName) {
|
||||
return getAutocompletionsForBehaviorExpressions(
|
||||
expressionAutocompletionContext,
|
||||
completionDescription
|
||||
completionDescription,
|
||||
useAllExpressionTypes
|
||||
);
|
||||
} else if (objectName) {
|
||||
return getAutocompletionsForObjectExpressions(
|
||||
expressionAutocompletionContext,
|
||||
completionDescription
|
||||
completionDescription,
|
||||
useAllExpressionTypes
|
||||
);
|
||||
} else {
|
||||
return getAutocompletionsForFreeExpressions(
|
||||
expressionAutocompletionContext,
|
||||
completionDescription
|
||||
completionDescription,
|
||||
useAllExpressionTypes
|
||||
);
|
||||
}
|
||||
} else if (completionKind === gd.ExpressionCompletionDescription.Object) {
|
||||
|
@@ -193,6 +193,7 @@ export type PreferencesValues = {|
|
||||
isAlwaysOnTopInPreview: boolean,
|
||||
backdropClickBehavior: 'nothing' | 'apply' | 'cancel',
|
||||
eventsSheetCancelInlineParameter: 'cancel' | 'apply',
|
||||
eventsSheetUseAllExpressionTypes: boolean,
|
||||
|};
|
||||
|
||||
/**
|
||||
@@ -251,6 +252,7 @@ export type Preferences = {|
|
||||
getIsAlwaysOnTopInPreview: () => boolean,
|
||||
setIsAlwaysOnTopInPreview: (enabled: boolean) => void,
|
||||
setEventsSheetCancelInlineParameter: (value: string) => void,
|
||||
setEventsSheetUseAllExpressionTypes: (enabled: boolean) => void,
|
||||
|};
|
||||
|
||||
export const initialPreferences = {
|
||||
@@ -287,6 +289,7 @@ export const initialPreferences = {
|
||||
isAlwaysOnTopInPreview: false,
|
||||
backdropClickBehavior: 'nothing',
|
||||
eventsSheetCancelInlineParameter: 'apply',
|
||||
eventsSheetUseAllExpressionTypes: false,
|
||||
},
|
||||
setLanguage: () => {},
|
||||
setThemeName: () => {},
|
||||
@@ -335,6 +338,7 @@ export const initialPreferences = {
|
||||
getIsAlwaysOnTopInPreview: () => true,
|
||||
setIsAlwaysOnTopInPreview: () => {},
|
||||
setEventsSheetCancelInlineParameter: () => {},
|
||||
setEventsSheetUseAllExpressionTypes: () => {},
|
||||
};
|
||||
|
||||
const PreferencesContext = React.createContext<Preferences>(initialPreferences);
|
||||
|
@@ -56,6 +56,7 @@ const PreferencesDialog = ({ i18n, onClose }: Props) => {
|
||||
setBackdropClickBehavior,
|
||||
setIsAlwaysOnTopInPreview,
|
||||
setEventsSheetCancelInlineParameter,
|
||||
setEventsSheetUseAllExpressionTypes,
|
||||
} = React.useContext(PreferencesContext);
|
||||
|
||||
return (
|
||||
@@ -282,6 +283,20 @@ const PreferencesDialog = ({ i18n, onClose }: Props) => {
|
||||
}
|
||||
/>
|
||||
</Line>
|
||||
<Line>
|
||||
<Toggle
|
||||
onToggle={(e, check) =>
|
||||
setEventsSheetUseAllExpressionTypes(check)
|
||||
}
|
||||
toggled={values.eventsSheetUseAllExpressionTypes}
|
||||
labelPosition="right"
|
||||
label={
|
||||
<Trans>
|
||||
Suggest all expressions regardless of returned type.
|
||||
</Trans>
|
||||
}
|
||||
/>
|
||||
</Line>
|
||||
<Line>
|
||||
<SelectField
|
||||
floatingLabelText={
|
||||
|
@@ -134,6 +134,9 @@ export default class PreferencesProvider extends React.Component<Props, State> {
|
||||
setEventsSheetCancelInlineParameter: this._setEventsSheetCancelInlineParameter.bind(
|
||||
this
|
||||
),
|
||||
setEventsSheetUseAllExpressionTypes: this._setEventsSheetUseAllExpressionTypes.bind(
|
||||
this
|
||||
),
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
@@ -317,6 +320,20 @@ export default class PreferencesProvider extends React.Component<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
_setEventsSheetUseAllExpressionTypes(
|
||||
eventsSheetUseAllExpressionTypes: boolean
|
||||
) {
|
||||
this.setState(
|
||||
state => ({
|
||||
values: {
|
||||
...state.values,
|
||||
eventsSheetUseAllExpressionTypes,
|
||||
},
|
||||
}),
|
||||
() => this._persistValuesToLocalStorage(this.state)
|
||||
);
|
||||
}
|
||||
|
||||
_checkUpdates(forceDownload?: boolean) {
|
||||
// Checking for updates is only done on Electron.
|
||||
// Note: This could be abstracted away later if other updates mechanisms
|
||||
|
Reference in New Issue
Block a user