Compare commits

...

2 Commits

Author SHA1 Message Date
Davy Hélard
e36d6018cb Typo 2022-04-15 21:19:36 +02:00
Davy Hélard
c0665dbba0 Hide advanced parameters and properties from beginners. 2022-04-15 20:54:09 +02:00
21 changed files with 353 additions and 63 deletions

View File

@@ -839,6 +839,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"edges, but are not overlapping (default: no)"),
"",
true)
.MarkParameterAsAdvanced()
.SetDefaultValue("no")
.MarkAsSimple();

View File

@@ -40,6 +40,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.MarkParameterAsAdvanced()
.SetDefaultValue("0")
.MarkAsAdvanced();
@@ -62,6 +63,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.MarkParameterAsAdvanced()
.SetDefaultValue("0")
.MarkAsAdvanced();
@@ -116,6 +118,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.MarkParameterAsAdvanced()
.SetDefaultValue("0")
.MarkAsAdvanced();
@@ -234,6 +237,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.MarkParameterAsAdvanced()
.SetDefaultValue("0");
// TODO Deprecated: hide this action in a future release.
@@ -262,10 +266,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Anticipate the movement of the object (yes by default)"),
"",
true)
.MarkParameterAsAdvanced()
.SetDefaultValue("yes")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.MarkParameterAsAdvanced()
.SetDefaultValue("0")
.MarkAsAdvanced();
@@ -291,6 +297,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.MarkParameterAsAdvanced()
.SetDefaultValue("0")
.MarkAsAdvanced();
@@ -309,10 +316,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Anticipate the movement of the object (yes by default)"),
"",
true)
.MarkParameterAsAdvanced()
.SetDefaultValue("yes")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.MarkParameterAsAdvanced()
.SetDefaultValue("0")
.MarkAsSimple();

View File

@@ -202,6 +202,18 @@ class GD_CORE_API InstructionMetadata {
return *this;
};
/**
* \brief Consider that the parameter is harder for a user to understand
* and not necessary for common usages.
*
* \see AddParameter
*/
InstructionMetadata &MarkParameterAsAdvanced() {
if (!parameters.empty())
parameters.back().MarkAsAdvanced();
return *this;
};
/**
* \brief Add the default parameters for an instruction manipulating the
* specified type ("string", "number") with the default operators.

View File

@@ -91,6 +91,18 @@ class GD_CORE_API MultipleInstructionMetadata {
return *this;
};
/**
* \brief Consider that the parameter is harder for a user to understand
* and not necessary for common usages.
*
* \see AddParameter
*/
MultipleInstructionMetadata &MarkParameterAsAdvanced() {
if (condition) condition->MarkParameterAsAdvanced();
if (action) action->MarkParameterAsAdvanced();
return *this;
};
/**
* \see gd::InstructionMetadata::SetHidden
*/

View File

@@ -10,7 +10,7 @@
namespace gd {
ParameterMetadata::ParameterMetadata() : optional(false), codeOnly(false) {}
ParameterMetadata::ParameterMetadata() : optional(false), codeOnly(false), usageComplexity(5) {}
void ParameterMetadata::SerializeTo(SerializerElement& element) const {
element.SetAttribute("type", type);
@@ -21,6 +21,7 @@ void ParameterMetadata::SerializeTo(SerializerElement& element) const {
element.SetAttribute("codeOnly", codeOnly);
element.SetAttribute("defaultValue", defaultValue);
element.SetAttribute("name", name);
element.SetAttribute("usageComplexity", usageComplexity);
}
void ParameterMetadata::UnserializeFrom(const SerializerElement& element) {
@@ -33,6 +34,7 @@ void ParameterMetadata::UnserializeFrom(const SerializerElement& element) {
codeOnly = element.GetBoolAttribute("codeOnly");
defaultValue = element.GetStringAttribute("defaultValue");
name = element.GetStringAttribute("name");
usageComplexity = element.GetIntAttribute("usageComplexity");
}
} // namespace gd

View File

@@ -151,6 +151,37 @@ class GD_CORE_API ParameterMetadata {
return *this;
}
/**
* \brief Consider that the parameter is easy for a user to understand.
*/
ParameterMetadata &MarkAsSimple() {
usageComplexity = 2;
return *this;
}
/**
* \brief Consider that the parameter is harder for a user to understand
* than a normal parameter.
*/
ParameterMetadata &MarkAsAdvanced() {
usageComplexity = 7;
return *this;
}
/**
* \brief Consider that the parameter is complex for a user to understand.
*/
ParameterMetadata &MarkAsComplex() {
usageComplexity = 9;
return *this;
}
/**
* \brief Return the usage complexity of this parameter for the user,
* from 0 (simple&easy to use) to 10 (complex to understand).
*/
int GetUsageComplexity() const { return usageComplexity; }
/**
* \brief Return true if the type of the parameter is "object", "objectPtr" or
* "objectList".
@@ -235,6 +266,8 @@ class GD_CORE_API ParameterMetadata {
///< optional parameter is empty.
gd::String name; ///< The name of the parameter to be used in code
///< generation. Optional.
int usageComplexity; ///< Evaluate the parameter from 0 (simple&easy to
///< use) to 10 (complex to understand)
};
} // namespace gd

View File

@@ -27,6 +27,7 @@ void PropertyDescriptor::SerializeTo(SerializerElement& element) const {
extraInformationElement.AddChild("").SetStringValue(information);
}
element.AddChild("hidden").SetBoolValue(hidden);
element.AddChild("usageComplexity").SetIntValue(usageComplexity);
}
void PropertyDescriptor::UnserializeFrom(const SerializerElement& element) {
@@ -47,6 +48,7 @@ void PropertyDescriptor::UnserializeFrom(const SerializerElement& element) {
hidden = element.HasChild("hidden")
? element.GetChild("hidden").GetBoolValue()
: false;
usageComplexity = element.GetChild("usageComplexity").GetIntValue();
}
void PropertyDescriptor::SerializeValuesTo(SerializerElement& element) const {

View File

@@ -28,12 +28,12 @@ class GD_CORE_API PropertyDescriptor {
* \param propertyValue The value of the property.
*/
PropertyDescriptor(gd::String propertyValue)
: currentValue(propertyValue), type("string"), label(""), hidden(false) {}
: currentValue(propertyValue), type("string"), label(""), hidden(false), usageComplexity(5) {}
/**
* \brief Empty constructor creating an empty property to be displayed.
*/
PropertyDescriptor() : hidden(false){};
PropertyDescriptor() : hidden(false), usageComplexity(5) {};
/**
* \brief Destructor
@@ -104,6 +104,37 @@ class GD_CORE_API PropertyDescriptor {
return *this;
}
/**
* \brief Consider that the property is easy for a user to understand.
*/
PropertyDescriptor &MarkAsSimple() {
usageComplexity = 2;
return *this;
}
/**
* \brief Consider that the property is harder for a user to understand
* than a normal property.
*/
PropertyDescriptor &MarkAsAdvanced() {
usageComplexity = 7;
return *this;
}
/**
* \brief Consider that the property is complex for a user to understand.
*/
PropertyDescriptor &MarkAsComplex() {
usageComplexity = 9;
return *this;
}
/**
* \brief Return the usage complexity of this property for the user,
* from 0 (simple&easy to use) to 10 (complex to understand).
*/
int GetUsageComplexity() const { return usageComplexity; }
const gd::String& GetValue() const { return currentValue; }
const gd::String& GetType() const { return type; }
const gd::String& GetLabel() const { return label; }
@@ -168,6 +199,8 @@ class GD_CORE_API PropertyDescriptor {
///< choices, if a property is a displayed as a combo
///< box.
bool hidden;
int usageComplexity; ///< Evaluate the parameter from 0 (simple&easy to
///< use) to 10 (complex to understand)
};
} // namespace gd

View File

@@ -88,7 +88,8 @@ PlatformerObjectBehavior::GetProperties(
.SetValue(behaviorContent.GetBoolAttribute("canGrabWithoutMoving", false)
? "true"
: "false")
.SetType("Boolean");
.SetType("Boolean")
.MarkAsAdvanced();
properties[_("Grab offset on Y axis")]
.SetGroup(_("Ledge"))
.SetValue(
@@ -104,13 +105,15 @@ PlatformerObjectBehavior::GetProperties(
.SetValue(behaviorContent.GetBoolAttribute("useLegacyTrajectory", true)
? "true"
: "false")
.SetType("Boolean");
.SetType("Boolean")
.MarkAsComplex();
properties[_("Can go down from jumpthru platforms")]
.SetGroup(_("Walk"))
.SetValue(behaviorContent.GetBoolAttribute("canGoDownFromJumpthru", false)
? "true"
: "false")
.SetType("Boolean");
.SetType("Boolean")
.MarkAsAdvanced();
return properties;
}

View File

@@ -87,20 +87,23 @@ TopDownMovementBehavior::GetProperties(
.AddExtraInfo(_("Top-Down"))
.AddExtraInfo(_("Isometry 2:1 (26.565°)"))
.AddExtraInfo(_("True Isometry (30°)"))
.AddExtraInfo(_("Custom Isometry"));
.AddExtraInfo(_("Custom Isometry"))
.MarkAsAdvanced();
properties[_("Custom isometry angle")]
.SetGroup(_("Viewpoint"))
.SetValue(gd::String::From(
behaviorContent.GetDoubleAttribute("customIsometryAngle")))
.SetDescription(_("If you choose \"Custom Isometry\", this allows to "
"specify the angle of your isometry projection."));
"specify the angle of your isometry projection."))
.MarkAsAdvanced();
properties[_("Movement angle offset")]
.SetGroup(_("Viewpoint"))
.SetValue(gd::String::From(
behaviorContent.GetDoubleAttribute("movementAngleOffset")))
.SetDescription(_(
"Usually 0, unless you choose an *Isometry* viewpoint in which case "
"-45 is recommended."));
"-45 is recommended."))
.MarkAsAdvanced();
return properties;
}

View File

@@ -773,6 +773,11 @@ interface PropertyDescriptor {
[Ref] VectorString GetExtraInfo();
[Ref] PropertyDescriptor SetHidden(boolean enable);
boolean IsHidden();
long GetUsageComplexity();
[Ref] PropertyDescriptor MarkAsSimple();
[Ref] PropertyDescriptor MarkAsAdvanced();
[Ref] PropertyDescriptor MarkAsComplex();
void SerializeTo([Ref] SerializerElement element);
void UnserializeFrom([Const, Ref] SerializerElement element);
@@ -1138,6 +1143,7 @@ interface InstructionMetadata {
[Ref] InstructionMetadata SetDefaultValue([Const] DOMString defaultValue);
[Ref] InstructionMetadata SetParameterLongDescription([Const] DOMString longDescription);
[Ref] InstructionMetadata SetParameterExtraInfo([Const] DOMString extraInfo);
[Ref] InstructionMetadata MarkParameterAsAdvanced();
[Ref] InstructionMetadata UseStandardOperatorParameters([Const] DOMString type);
[Ref] InstructionMetadata UseStandardRelationalOperatorParameters([Const] DOMString type);
@@ -1200,6 +1206,7 @@ interface MultipleInstructionMetadata {
[Const] DOMString type, [Const] DOMString supplementaryInformation);
[Ref] MultipleInstructionMetadata SetDefaultValue([Const] DOMString defaultValue);
[Ref] MultipleInstructionMetadata SetParameterLongDescription([Const] DOMString longDescription);
[Ref] MultipleInstructionMetadata MarkParameterAsAdvanced();
[Ref] MultipleInstructionMetadata UseStandardParameters([Const] DOMString type);
@@ -1255,6 +1262,10 @@ interface ParameterMetadata {
[Ref] ParameterMetadata SetCodeOnly(boolean codeOnly_);
[Const, Ref] DOMString GetDefaultValue();
[Ref] ParameterMetadata SetDefaultValue([Const] DOMString defaultValue_);
[Ref] ParameterMetadata MarkAsSimple();
[Ref] ParameterMetadata MarkAsAdvanced();
[Ref] ParameterMetadata MarkAsComplex();
long GetUsageComplexity();
boolean STATIC_IsObject([Const] DOMString param);
boolean STATIC_IsBehavior([Const] DOMString param);

View File

@@ -24,6 +24,7 @@ declare class gdInstructionMetadata {
setDefaultValue(defaultValue: string): gdInstructionMetadata;
setParameterLongDescription(longDescription: string): gdInstructionMetadata;
setParameterExtraInfo(extraInfo: string): gdInstructionMetadata;
markParameterAsAdvanced(): gdInstructionMetadata;
useStandardOperatorParameters(type: string): gdInstructionMetadata;
useStandardRelationalOperatorParameters(type: string): gdInstructionMetadata;
setRequiresBaseObjectCapability(capability: string): gdInstructionMetadata;

View File

@@ -4,6 +4,7 @@ declare class gdMultipleInstructionMetadata {
addCodeOnlyParameter(type: string, supplementaryInformation: string): gdMultipleInstructionMetadata;
setDefaultValue(defaultValue: string): gdMultipleInstructionMetadata;
setParameterLongDescription(longDescription: string): gdMultipleInstructionMetadata;
markParameterAsAdvanced(): gdMultipleInstructionMetadata;
useStandardParameters(type: string): gdMultipleInstructionMetadata;
setHidden(): gdMultipleInstructionMetadata;
setFunctionName(functionName: string): gdMultipleInstructionMetadata;

View File

@@ -17,6 +17,10 @@ declare class gdParameterMetadata {
setCodeOnly(codeOnly_: boolean): gdParameterMetadata;
getDefaultValue(): string;
setDefaultValue(defaultValue_: string): gdParameterMetadata;
markAsSimple(): gdParameterMetadata;
markAsAdvanced(): gdParameterMetadata;
markAsComplex(): gdParameterMetadata;
getUsageComplexity(): number;
static isObject(param: string): boolean;
static isBehavior(param: string): boolean;
serializeTo(element: gdSerializerElement): void;

View File

@@ -16,6 +16,10 @@ declare class gdPropertyDescriptor {
getExtraInfo(): gdVectorString;
setHidden(enable: boolean): gdPropertyDescriptor;
isHidden(): boolean;
getUsageComplexity(): number;
markAsSimple(): gdPropertyDescriptor;
markAsAdvanced(): gdPropertyDescriptor;
markAsComplex(): gdPropertyDescriptor;
serializeTo(element: gdSerializerElement): void;
unserializeFrom(element: gdSerializerElement): void;
serializeValuesTo(element: gdSerializerElement): void;

View File

@@ -10,6 +10,7 @@ import { mapFor } from '../../Utils/MapFor';
import EmptyMessage from '../../UI/EmptyMessage';
import ParameterRenderingService from '../ParameterRenderingService';
import HelpButton from '../../UI/HelpButton';
import FlatButton from '../../UI/FlatButton';
import {
type ResourceSource,
type ChooseResourceFunction,
@@ -32,6 +33,7 @@ import { ColumnStackLayout } from '../../UI/Layout';
import { setupInstructionParameters } from '../../InstructionOrExpression/SetupInstructionParameters';
import ScrollView from '../../UI/ScrollView';
import { getInstructionTutorialIds } from '../../Utils/GDevelopServices/Tutorial';
import PreferencesContext from '../../MainFrame/Preferences/PreferencesContext';
const gd: libGDevelop = global.gd;
const styles = {
@@ -80,6 +82,7 @@ type Props = {|
|};
type State = {|
isDirty: boolean,
showAdvancedParameter: boolean,
|};
const isParameterVisible = (
@@ -100,9 +103,13 @@ export default class InstructionParametersEditor extends React.Component<
Props,
State
> {
static contextType = PreferencesContext;
_firstVisibleField: ?any = {};
state = {
isDirty: false,
showAdvancedParameter: this.context.values
.showAdvancedParametersAndProperties,
};
componentDidMount() {
@@ -233,6 +240,9 @@ export default class InstructionParametersEditor extends React.Component<
objectName
);
const preferences = this.context;
let anyAdvancedParameterIsHidden = false;
let parameterFieldIndex = 0;
return (
<I18n>
@@ -306,6 +316,15 @@ export default class InstructionParametersEditor extends React.Component<
)
return null;
if (
!this.state.showAdvancedParameter &&
parameterMetadata.isOptional() &&
parameterMetadata.getUsageComplexity() > 5
) {
anyAdvancedParameterIsHidden = true;
return null;
}
const parameterMetadataType = parameterMetadata.getType();
const ParameterComponent = ParameterRenderingService.getParameterComponent(
parameterMetadataType
@@ -351,6 +370,28 @@ export default class InstructionParametersEditor extends React.Component<
/>
);
})}
{!this.state.showAdvancedParameter &&
anyAdvancedParameterIsHidden && (
<FlatButton
label={<Trans>Show advanced parameters</Trans>}
onClick={() =>
this.setState({
showAdvancedParameter: true,
})
}
/>
)}
{this.state.showAdvancedParameter &&
!preferences.values.showAdvancedParametersAndProperties && (
<FlatButton
label={<Trans>Always show advanced parameters</Trans>}
onClick={() =>
preferences.setShowAdvancedParametersAndProperties(
true
)
}
/>
)}
</ColumnStackLayout>
{this._getVisibleParametersCount(
instructionMetadata,

View File

@@ -193,6 +193,7 @@ export type PreferencesValues = {|
isAlwaysOnTopInPreview: boolean,
backdropClickBehavior: 'nothing' | 'apply' | 'cancel',
eventsSheetCancelInlineParameter: 'cancel' | 'apply',
showAdvancedParametersAndProperties: boolean,
|};
/**
@@ -251,6 +252,8 @@ export type Preferences = {|
getIsAlwaysOnTopInPreview: () => boolean,
setIsAlwaysOnTopInPreview: (enabled: boolean) => void,
setEventsSheetCancelInlineParameter: (value: string) => void,
getShowAdvancedParametersAndProperties: () => boolean,
setShowAdvancedParametersAndProperties: (enabled: boolean) => void,
|};
export const initialPreferences = {
@@ -286,6 +289,7 @@ export const initialPreferences = {
isAlwaysOnTopInPreview: false,
backdropClickBehavior: 'nothing',
eventsSheetCancelInlineParameter: 'apply',
showAdvancedParametersAndProperties: false,
},
setLanguage: () => {},
setThemeName: () => {},
@@ -334,6 +338,8 @@ export const initialPreferences = {
getIsAlwaysOnTopInPreview: () => true,
setIsAlwaysOnTopInPreview: () => {},
setEventsSheetCancelInlineParameter: () => {},
getShowAdvancedParametersAndProperties: () => true,
setShowAdvancedParametersAndProperties: (enabled: boolean) => {},
};
const PreferencesContext = React.createContext<Preferences>(initialPreferences);

View File

@@ -44,6 +44,7 @@ const PreferencesDialog = ({ i18n, onClose }: Props) => {
setAutosaveOnPreview,
setUseNewInstructionEditorDialog,
setUseUndefinedVariablesInAutocompletion,
setShowAdvancedParametersAndProperties,
setUseGDJSDevelopmentWatcher,
setEventsSheetUseAssignmentOperators,
getDefaultEditorMosaicNode,
@@ -274,6 +275,18 @@ const PreferencesDialog = ({ i18n, onClose }: Props) => {
}
/>
</Line>
<Line>
<Toggle
onToggle={(e, check) =>
setShowAdvancedParametersAndProperties(check)
}
toggled={values.showAdvancedParametersAndProperties}
labelPosition="right"
label={
<Trans>Always show advanced parameters and properties</Trans>
}
/>
</Line>
<Line>
<SelectField
floatingLabelText={

View File

@@ -103,6 +103,12 @@ export default class PreferencesProvider extends React.Component<Props, State> {
setUseUndefinedVariablesInAutocompletion: this._setUseUndefinedVariablesInAutocompletion.bind(
this
),
getShowAdvancedParametersAndProperties: this._getShowAdvancedParametersAndProperties.bind(
this
),
setShowAdvancedParametersAndProperties: this._setShowAdvancedParametersAndProperties.bind(
this
),
setUseGDJSDevelopmentWatcher: this._setUseGDJSDevelopmentWatcher.bind(this),
setEventsSheetUseAssignmentOperators: this._setEventsSheetUseAssignmentOperators.bind(
this
@@ -205,6 +211,26 @@ export default class PreferencesProvider extends React.Component<Props, State> {
);
}
_getShowAdvancedParametersAndProperties(
showAdvancedParametersAndProperties: boolean
) {
return this.state.values.showAdvancedParametersAndProperties;
}
_setShowAdvancedParametersAndProperties(
showAdvancedParametersAndProperties: boolean
) {
this.setState(
state => ({
values: {
...state.values,
showAdvancedParametersAndProperties,
},
}),
() => this._persistValuesToLocalStorage(this.state)
);
}
_setUseGDJSDevelopmentWatcher(useGDJSDevelopmentWatcher: boolean) {
this.setState(
state => ({

View File

@@ -37,6 +37,7 @@ export default (
const propertyDescription = property.getDescription();
const valueType = property.getType().toLowerCase();
const usageComplexity = property.getUsageComplexity();
const getLabel = (instance: Instance) => {
const propertyName = getProperties(instance)
.get(name)
@@ -72,6 +73,7 @@ export default (
},
getLabel,
getDescription,
usageComplexity,
});
return null;
} else if (valueType === 'string' || valueType === '') {
@@ -88,6 +90,7 @@ export default (
},
getLabel,
getDescription,
usageComplexity,
});
return null;
} else if (valueType === 'boolean') {
@@ -106,6 +109,7 @@ export default (
},
getLabel,
getDescription,
usageComplexity,
});
return null;
} else if (valueType === 'choice') {
@@ -128,6 +132,7 @@ export default (
},
getLabel,
getDescription,
usageComplexity,
});
return null;
} else if (valueType === 'behavior') {
@@ -160,6 +165,7 @@ export default (
},
getLabel,
getDescription,
usageComplexity,
});
return null;
} else if (valueType === 'resource') {
@@ -180,6 +186,7 @@ export default (
},
getLabel,
getDescription,
usageComplexity,
});
return null;
} else if (valueType === 'color') {
@@ -196,6 +203,7 @@ export default (
},
getLabel,
getDescription,
usageComplexity,
});
return null;
} else if (valueType === 'textarea') {
@@ -212,6 +220,7 @@ export default (
},
getLabel,
getDescription,
usageComplexity,
});
return null;
} else {

View File

@@ -26,12 +26,14 @@ import {
ColumnStackLayout,
} from '../UI/Layout';
import RaisedButton from '../UI/RaisedButton';
import FlatButton from '../UI/FlatButton';
import UnsavedChangesContext, {
type UnsavedChanges,
} from '../MainFrame/UnsavedChangesContext';
import { Line, Spacer } from '../UI/Grid';
import Text from '../UI/Text';
import useForceUpdate from '../Utils/UseForceUpdate';
import PreferencesContext from '../MainFrame/Preferences/PreferencesContext';
// An "instance" here is the objects for which properties are shown
export type Instance = Object; // This could be improved using generics.
@@ -45,6 +47,7 @@ export type ValueFieldCommonProperties = {|
getExtraDescription?: Instance => string,
disabled?: boolean,
onEditButtonClick?: Instance => void,
usageComplexity?: number,
|};
// "Primitive" value fields are "simple" fields.
@@ -140,6 +143,7 @@ type Props = {|
resourceSources?: ?Array<ResourceSource>,
onChooseResource?: ?ChooseResourceFunction,
resourceExternalEditors?: ?Array<ResourceExternalEditor>,
shouldShowAdvancedProperties?: boolean,
|};
const styles = {
@@ -210,6 +214,22 @@ const getFieldLabel = (instances: Instances, field: ValueField): any => {
return field.name;
};
const containsAdvancedFields = (schema: Schema): boolean => {
return schema.some(
field =>
(field.usageComplexity && field.usageComplexity > 5) ||
(field.children && containsAdvancedFields(field.children))
);
};
const containsBasicFields = (schema: Schema): boolean => {
return schema.some(
field =>
!(field.usageComplexity && field.usageComplexity > 5) ||
(field.children && containsBasicFields(field.children))
);
};
const PropertiesEditor = ({
onInstancesModified,
instances,
@@ -221,9 +241,23 @@ const PropertiesEditor = ({
resourceSources,
onChooseResource,
resourceExternalEditors,
shouldShowAdvancedProperties,
}: Props) => {
const forceUpdate = useForceUpdate();
const {
getShowAdvancedParametersAndProperties,
setShowAdvancedParametersAndProperties,
} = React.useContext(PreferencesContext);
let [
showAdvancedProperties,
setShowAdvancedProperties,
] = React.useState<boolean>(getShowAdvancedParametersAndProperties());
if (shouldShowAdvancedProperties !== undefined) {
showAdvancedProperties = shouldShowAdvancedProperties;
}
const _onInstancesModified = React.useCallback(
(instances: Instances) => {
// This properties editor is dealing with fields that are
@@ -548,18 +582,58 @@ const PropertiesEditor = ({
[instances]
);
return renderContainer(
schema.map(field => {
if (!!field.nonFieldType) {
if (field.nonFieldType === 'sectionTitle') {
return renderSectionTitle(field);
} else if (field.nonFieldType === 'button') {
return renderButton(field);
}
const fieldComponents = schema.map(field => {
if (
!showAdvancedProperties &&
field.usageComplexity &&
field.usageComplexity > 5
) {
return null;
}
if (!!field.nonFieldType) {
if (field.nonFieldType === 'sectionTitle') {
return renderSectionTitle(field);
} else if (field.nonFieldType === 'button') {
return renderButton(field);
}
return null;
} else if (field.children) {
if (!showAdvancedProperties && !containsBasicFields(field.children)) {
return null;
} else if (field.children) {
if (field.type === 'row') {
const contentView = (
}
if (field.type === 'row') {
const contentView = (
<UnsavedChangesContext.Consumer key={field.name}>
{unsavedChanges => (
<PropertiesEditor
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
schema={field.children}
instances={instances}
mode="row"
unsavedChanges={unsavedChanges}
onInstancesModified={onInstancesModified}
/>
)}
</UnsavedChangesContext.Consumer>
);
if (field.title) {
return [
<Text key={field.name + '-title'} size="title">
{field.title}
</Text>,
contentView,
];
}
return contentView;
}
return (
<div key={field.name}>
<Subheader>{field.name}</Subheader>
<div style={styles.subPropertiesEditorContainer}>
<UnsavedChangesContext.Consumer key={field.name}>
{unsavedChanges => (
<PropertiesEditor
@@ -569,55 +643,45 @@ const PropertiesEditor = ({
resourceExternalEditors={resourceExternalEditors}
schema={field.children}
instances={instances}
mode="row"
mode="column"
unsavedChanges={unsavedChanges}
onInstancesModified={onInstancesModified}
shouldShowAdvancedProperties={showAdvancedProperties}
/>
)}
</UnsavedChangesContext.Consumer>
);
if (field.title) {
return [
<Text key={field.name + '-title'} size="title">
{field.title}
</Text>,
contentView,
];
}
return contentView;
}
return (
<div key={field.name}>
<Subheader>{field.name}</Subheader>
<div style={styles.subPropertiesEditorContainer}>
<UnsavedChangesContext.Consumer key={field.name}>
{unsavedChanges => (
<PropertiesEditor
project={project}
resourceSources={resourceSources}
onChooseResource={onChooseResource}
resourceExternalEditors={resourceExternalEditors}
schema={field.children}
instances={instances}
mode="column"
unsavedChanges={unsavedChanges}
onInstancesModified={onInstancesModified}
/>
)}
</UnsavedChangesContext.Consumer>
</div>
</div>
);
} else if (field.valueType === 'resource') {
return renderResourceField(field);
} else {
if (field.getChoices && field.getValue) return renderSelectField(field);
if (field.getValue) return renderInputField(field);
}
return null;
})
);
</div>
);
} else if (field.valueType === 'resource') {
return renderResourceField(field);
} else {
if (field.getChoices && field.getValue) return renderSelectField(field);
if (field.getValue) return renderInputField(field);
}
return null;
});
if (shouldShowAdvancedProperties === undefined) {
if (!showAdvancedProperties && containsAdvancedFields(schema)) {
fieldComponents.push(
<FlatButton
key="show-advanced-properties"
label={<Trans>Show advanced properties</Trans>}
onClick={() => setShowAdvancedProperties(true)}
/>
);
}
if (showAdvancedProperties && !getShowAdvancedParametersAndProperties()) {
fieldComponents.push(
<FlatButton
key="always-show-advanced-properties"
label={<Trans>Always show advanced properties</Trans>}
onClick={() => setShowAdvancedParametersAndProperties(true)}
/>
);
}
}
return renderContainer(fieldComponents);
};
export default PropertiesEditor;