import React from "react"; import { observer } from "mobx-react"; import { EezObject, findPropertyByNameInClassInfo, FlowPropertyType, getProperty, IEezObject, IOnSelectParams, PropertyInfo, PropertyProps, PropertyType } from "project-editor/core/object"; import { ProjectContext } from "project-editor/project/context"; import { getClassInfo } from "project-editor/store"; import { findBitmap } from "project-editor/project/project"; import { Property } from "project-editor/ui-components/PropertyGrid/Property"; import { expressionBuilder } from "project-editor/flow/expression/ExpressionBuilder"; import type { LVGLWidget } from "project-editor/lvgl/widgets"; import { ProjectEditor } from "project-editor/project-editor-interface"; import { getPropertyValue } from "project-editor/ui-components/PropertyGrid/utils"; import { ValueType } from "eez-studio-types"; import { ASSIGNABLE_ICON, EXPRESSION_ICON, LITERAL_BOOLEAN_ICON, LITERAL_COLOR_ICON, LITERAL_ENUM_ICON, LITERAL_NUMBER_ICON, LITERAL_STRING_ICON, TRANSLATED_LITERAL_ICON } from "project-editor/ui-components/icons"; import { capitalize } from "eez-studio-shared/string"; export type LVGLPropertyType = "literal" | "translated-literal" | "expression"; const LVGLProperty = observer( class LVGLProperty extends React.Component { static contextType = ProjectContext; declare context: React.ContextType; render() { const { propertyInfo, objects, updateObject, readOnly } = this.props; const classInfo = getClassInfo(this.props.objects[0]); const typePropertyInfo = findPropertyByNameInClassInfo( classInfo, propertyInfo.name + "Type" )!; const type: LVGLPropertyType = (objects[0] as any)[ typePropertyInfo.name ]; let propertyInfoType; if (propertyInfo.dynamicType) { propertyInfoType = propertyInfo.dynamicType(objects[0]); } else { propertyInfoType = propertyInfo.colorEditorForLiteral ? PropertyType.ThemedColor : propertyInfo.expressionType == "integer" ? PropertyType.Number : propertyInfo.expressionType == "string" || propertyInfo.expressionType == "array:string" ? PropertyType.MultilineText : propertyInfo.expressionType == "boolean" ? PropertyType.Boolean : propertyInfo.type; } let referencedObjectCollectionPath = propertyInfo.referencedObjectCollectionPath; if (propertyInfo.dynamicTypeReferencedObjectCollectionPath) { referencedObjectCollectionPath = propertyInfo.dynamicTypeReferencedObjectCollectionPath( objects[0] ); } const valuePropertyInfo = Object.assign({}, propertyInfo, { type: type == "expression" ? this.context.projectTypeTraits.hasFlowSupport ? PropertyType.MultilineText : PropertyType.ObjectReference : propertyInfoType, checkboxStyleSwitch: true, referencedObjectCollectionPath: type == "expression" ? "variables/globalVariables" : referencedObjectCollectionPath, propertyGridColumnComponent: undefined, disableBitmapPreview: true, onSelect: type == "expression" ? ( object: IEezObject, propertyInfo: PropertyInfo, params: IOnSelectParams ) => expressionBuilder( object, propertyInfo, { assignableExpression: false, title: "Expression Builder" }, params ) : undefined, isOnSelectAvailable: () => { return ( type == "expression" && this.context.projectTypeTraits.hasFlowSupport ); }, formText: propertyInfo.formText } as Partial); let bitmap; if (referencedObjectCollectionPath === "bitmaps") { const getPropertyValueResult = getPropertyValue( objects, propertyInfo ); if (getPropertyValueResult) { bitmap = findBitmap( this.context.project, getPropertyValueResult.value ); } } return ( <>
{bitmap && bitmap.imageSrc && ( )} ); } } ); export function makeLvglExpressionProperty( name: string, expressionType: ValueType, flowProperty: FlowPropertyType, types: LVGLPropertyType[], props: Partial ) { return [ Object.assign( { name, type: PropertyType.ObjectReference, referencedObjectCollectionPath: "variables/globalVariables", propertyGridColumnComponent: LVGLProperty, flowProperty: (widget: LVGLWidget | undefined) => { if (widget == undefined) { return flowProperty; } return (widget as any)[name + "Type"] == "expression" ? flowProperty : undefined; }, isFlowPropertyBuildable: (widget: LVGLWidget, propertyInfo) => { return ( getProperty(widget, propertyInfo.name + "Type") == "expression" ); }, expressionType, disableSpellcheck: true } as PropertyInfo, props ), { name: name + "Type", type: PropertyType.Enum, enumItems: (object: EezObject) => types.map(id => { let label: string; let icon: React.ReactNode; function getLiteralLabel() { let propertyType; if (props.dynamicType) { propertyType = props.dynamicType(object) } return propertyType && propertyType == PropertyType.ThemedColor || props.colorEditorForLiteral ? "Literal - Color" : propertyType && propertyType == PropertyType.Enum ? "Literal - Enumeration" : expressionType == "boolean" ? "Literal - Boolean" : expressionType == "integer" || expressionType == "float" || expressionType == "double" ? `Literal - ${capitalize(expressionType)}` : "Literal - String"; } function getLiteralIcon() { let propertyType; if (props.dynamicType) { propertyType = props.dynamicType(object) } return propertyType && propertyType == PropertyType.ThemedColor || props.colorEditorForLiteral ? LITERAL_COLOR_ICON : propertyType && propertyType == PropertyType.Enum ? LITERAL_ENUM_ICON : expressionType == "boolean" ? LITERAL_BOOLEAN_ICON : expressionType == "integer" || expressionType == "float" || expressionType == "double" ? LITERAL_NUMBER_ICON : LITERAL_STRING_ICON; } if ( !ProjectEditor.getProject(object).projectTypeTraits .hasFlowSupport ) { if (id == "expression") { label = "Variable"; icon = EXPRESSION_ICON; } else if (id == "translated-literal") { label = "Translated Literal"; icon = TRANSLATED_LITERAL_ICON; } else { label = getLiteralLabel(); icon = getLiteralIcon(); } } else { if (id == "expression") { if (flowProperty == "assignable") { label = "Assignable"; icon = ASSIGNABLE_ICON; } else { label = "Expression"; icon = EXPRESSION_ICON; } } else if (id == "translated-literal") { label = "Translated Literal"; icon = TRANSLATED_LITERAL_ICON; } else { label = getLiteralLabel(); icon = getLiteralIcon(); } } return { id, label, icon }; }), enumDisallowUndefined: true, propertyGridGroup: props.propertyGridGroup, hideInPropertyGrid: true } as PropertyInfo ]; }