import React from "react"; import { observable, makeObservable } from "mobx"; import { PropertyType, makeDerivedClassInfo } from "project-editor/core/object"; import { Project, ProjectType } from "project-editor/project/project"; import { specificGroup } from "project-editor/ui-components/PropertyGrid/groups"; import { LVGLWidget } from "./internal"; import { LVGLPropertyType, makeLvglExpressionProperty } from "../expression-property"; import type { LVGLCode } from "project-editor/lvgl/to-lvgl-code"; //////////////////////////////////////////////////////////////////////////////// export class LVGLTextareaWidget extends LVGLWidget { text: string; textType: LVGLPropertyType; placeholder: string; oneLineMode: boolean; passwordMode: boolean; acceptedCharacters: string; maxTextLength: number; static classInfo = makeDerivedClassInfo(LVGLWidget.classInfo, { enabledInComponentPalette: (projectType: ProjectType) => projectType === ProjectType.LVGL, componentPaletteGroupName: "!1Basic", properties: [ ...makeLvglExpressionProperty( "text", "string", "input", ["literal", "translated-literal", "expression"], { propertyGridGroup: specificGroup } ), { name: "placeholder", type: PropertyType.String, propertyGridGroup: specificGroup }, { name: "oneLineMode", type: PropertyType.Boolean, propertyGridGroup: specificGroup }, { name: "passwordMode", type: PropertyType.Boolean, propertyGridGroup: specificGroup }, { name: "acceptedCharacters", type: PropertyType.String, propertyGridGroup: specificGroup }, { name: "maxTextLength", type: PropertyType.Number, propertyGridGroup: specificGroup } ], defaultValue: { left: 0, top: 0, width: 150, height: 70, clickableFlag: true, text: "", textType: "literal", placeholder: "", oneLineMode: false, passwordMode: false, acceptedCharacters: "", maxTextLength: 128 }, icon: ( ), lvgl: (widget: LVGLTextareaWidget, project: Project) => { return { parts: ["MAIN", "SELECTED", "CURSOR"], defaultFlags: project.settings.general.lvglVersion == "9.0" ? "CLICKABLE|CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_ON_FOCUS|SNAPPABLE" : "CLICKABLE|CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLLABLE|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_ON_FOCUS|SCROLL_WITH_ARROW|SNAPPABLE", states: ["CHECKED", "DISABLED", "FOCUSED", "PRESSED"], oldInitFlags: "PRESS_LOCK|CLICK_FOCUSABLE|GESTURE_BUBBLE|SNAPPABLE|SCROLLABLE|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_CHAIN", oldDefaultFlags: "CLICKABLE|PRESS_LOCK|CLICK_FOCUSABLE|GESTURE_BUBBLE|SNAPPABLE|SCROLLABLE|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_CHAIN" }; } }); override makeEditable() { super.makeEditable(); makeObservable(this, { text: observable, textType: observable, placeholder: observable, oneLineMode: observable, passwordMode: observable, acceptedCharacters: observable, maxTextLength: observable }); } override toLVGLCode(code: LVGLCode) { code.createObject(`lv_textarea_create`); // acceptedCharacters if (this.acceptedCharacters) { code.callObjectFunction( "lv_textarea_set_accepted_chars", code.stringProperty("literal", this.acceptedCharacters) ); } // maxTextLength code.callObjectFunction( "lv_textarea_set_max_length", this.maxTextLength ?? 128 ); // text if (this.text) { if ( this.textType == "literal" || this.textType == "translated-literal" ) { code.callObjectFunction( "lv_textarea_set_text", code.stringProperty(this.textType, this.text) ); } else { code.addToTick("text", () => { const new_val = code.evalTextProperty( "const char *", "new_val", this.text, "Failed to evaluate Text in Textarea widget" ); const cur_val = code.callObjectFunctionWithAssignment( "const char *", "cur_val", "lv_textarea_get_text" ); code.ifStringNotEqual(new_val, cur_val, () => { code.tickChangeStart(); code.callObjectFunction( "lv_textarea_set_text", new_val ); code.tickChangeEnd(); }); }); code.addEventHandler( "VALUE_CHANGED", (event, tick_value_change_obj) => { const ta = code.callFreeFunctionWithAssignment( "lv_obj_t *", "ta", "lv_event_get_target", event ); code.ifIntegerNotEqual( tick_value_change_obj, ta, () => { const value = code.callFreeFunctionWithAssignment( "const char *", "value", "lv_textarea_get_text", ta ); code.assignStringProperty( "text", this.text as string, value, "Failed to assign Text in Textarea widget" ); } ); } ); } } // placeholder if (this.placeholder) { code.callObjectFunction( "lv_textarea_set_placeholder_text", code.stringProperty("literal", this.placeholder) ); } // oneLineMode code.callObjectFunction( "lv_textarea_set_one_line", code.constant(this.oneLineMode ? "true" : "false") ); // passwordMode code.callObjectFunction( "lv_textarea_set_password_mode", code.constant(this.passwordMode ? "true" : "false") ); } }