diff --git a/packages/eez-studio-types/index.d.ts b/packages/eez-studio-types/index.d.ts index 00beff2d..b85dc523 100644 --- a/packages/eez-studio-types/index.d.ts +++ b/packages/eez-studio-types/index.d.ts @@ -725,7 +725,7 @@ export interface IWasmFlowRuntime { _lvglFreeFont(font_ptr: number): void; _lvglAddObjectFlowCallback(obj: number, filter: number, flow_state: number, component_index: number, output_or_property_index: number, userDataValuePtr: number): void; _lvglSetImgbuttonImageSrc(obj: number, statE: number, img_src: number): void; - _lvglSetKeyboardTextarea(obj: number, textareaIndex: number): void; + _lvglSetKeyboardTextarea(keyboardIndex: number, textareaIndex: number): void; _lvglMeterAddScale(obj: number, minorTickCount: number, minorTickLineWidth: number, minorTickLength: number, minorTickColor: number, diff --git a/packages/project-editor/features/page/page.tsx b/packages/project-editor/features/page/page.tsx index b641bc9f..ffea49e5 100644 --- a/packages/project-editor/features/page/page.tsx +++ b/packages/project-editor/features/page/page.tsx @@ -69,10 +69,7 @@ import { LVGLPage } from "project-editor/lvgl/Page"; import type { LVGLPageRuntime } from "project-editor/lvgl/page-runtime"; import type { LVGLBuild } from "project-editor/lvgl/build"; import { visitObjects } from "project-editor/core/search"; -import type { - LVGLUserWidgetWidget, - LVGLWidget -} from "project-editor/lvgl/widgets"; +import type { LVGLWidget } from "project-editor/lvgl/widgets"; import { lvglBuildPageTimeline } from "project-editor/flow/timeline"; import type { ProjectEditorFeature } from "project-editor/store/features"; import { PAGES_ICON } from "project-editor/ui-components/icons"; @@ -215,7 +212,6 @@ export class Page extends Flow { _lvglRuntime: LVGLPageRuntime | undefined; _lvglObj: number | undefined; - _lvglUserWidgetOfPageCopy: LVGLUserWidgetWidget; get codeIdentifier() { const codeIdentifier = getName( @@ -237,8 +233,7 @@ export class Page extends Flow { makeObservable(this, { dataContextOverridesObject: computed, rect: computed, - _lvglWidgetsIncludingUserWidgets: computed({ keepAlive: true }), - _lvglWidgetsIncludingUserWidgetsWithoutCopy: computed({ + _lvglWidgetsIncludingUserWidgets: computed({ keepAlive: true }), _lvglWidgets: computed({ keepAlive: true }) @@ -1112,8 +1107,7 @@ export class Page extends Flow { getLvglGroupWidgets(groupName: string) { let groupWidgets: LVGLWidget[][] = []; - for (const widgetPath of this - ._lvglWidgetsIncludingUserWidgetsWithoutCopy) { + for (const widgetPath of this._lvglWidgetsIncludingUserWidgets) { if (widgetPath[widgetPath.length - 1].group == groupName) { groupWidgets.push(widgetPath); } @@ -1159,32 +1153,6 @@ export class Page extends Flow { } get _lvglWidgetsIncludingUserWidgets() { - const widgets: LVGLWidget[] = []; - - function addWidgets(page: Page) { - for (const widget of visitObjects(page.components)) { - if (widget instanceof ProjectEditor.LVGLWidgetClass) { - widgets.push(widget); - - if ( - widget instanceof - ProjectEditor.LVGLUserWidgetWidgetClass - ) { - const userWidgetPageCopy = widget.userWidgetPageCopy; - if (userWidgetPageCopy && !widget.isCycleDetected) { - addWidgets(userWidgetPageCopy); - } - } - } - } - } - - addWidgets(this); - - return widgets; - } - - get _lvglWidgetsIncludingUserWidgetsWithoutCopy() { const allWidgets: LVGLWidget[][] = []; function addWidgets(page: Page, widgetPath: LVGLWidget[]) { diff --git a/packages/project-editor/flow/runtime/lvgl_runtime_v8.3.wasm b/packages/project-editor/flow/runtime/lvgl_runtime_v8.3.wasm index 354c0460..f18e3af7 100644 Binary files a/packages/project-editor/flow/runtime/lvgl_runtime_v8.3.wasm and b/packages/project-editor/flow/runtime/lvgl_runtime_v8.3.wasm differ diff --git a/packages/project-editor/flow/runtime/lvgl_runtime_v9.0.wasm b/packages/project-editor/flow/runtime/lvgl_runtime_v9.0.wasm index de0c53b0..db965cb7 100644 Binary files a/packages/project-editor/flow/runtime/lvgl_runtime_v9.0.wasm and b/packages/project-editor/flow/runtime/lvgl_runtime_v9.0.wasm differ diff --git a/packages/project-editor/lvgl/build.ts b/packages/project-editor/lvgl/build.ts index 3515c78a..cd62d014 100644 --- a/packages/project-editor/lvgl/build.ts +++ b/packages/project-editor/lvgl/build.ts @@ -172,10 +172,18 @@ export class LVGLBuild extends Build { NamingConvention.UnderscoreLowerCase ); } else { - identifier = generateUniqueObjectName(); - this.assets.map.lvglWidgetGeneratedIdentifiers[ - widget.objID - ] = identifier; + identifier = + this.assets.map.lvglWidgetGeneratedIdentifiers[ + widget.objID + ]; + + if (!identifier) { + identifier = generateUniqueObjectName(); + + this.assets.map.lvglWidgetGeneratedIdentifiers[ + widget.objID + ] = identifier; + } } pageIdentifiers.widgetToIdentifier.set( diff --git a/packages/project-editor/lvgl/identifiers.ts b/packages/project-editor/lvgl/identifiers.ts index 86106a3e..d3bf1493 100644 --- a/packages/project-editor/lvgl/identifiers.ts +++ b/packages/project-editor/lvgl/identifiers.ts @@ -173,18 +173,6 @@ export class LVGLIdentifiers { let identifiers = this.getIdentifiersVisibleFromFlow(flow); - if (!identifiers) { - if ( - flow instanceof ProjectEditor.PageClass && - flow._lvglUserWidgetOfPageCopy - ) { - identifiers = []; - this.enumIdentifiers(flow, identifiers, ""); - } else { - return undefined; - } - } - return identifiers.find( lvglIdentifier => lvglIdentifier.identifier == identifierName ); diff --git a/packages/project-editor/lvgl/page-runtime.ts b/packages/project-editor/lvgl/page-runtime.ts index 2de9caa3..e771269e 100644 --- a/packages/project-editor/lvgl/page-runtime.ts +++ b/packages/project-editor/lvgl/page-runtime.ts @@ -123,6 +123,10 @@ export abstract class LVGLPageRuntime { beginUserWidget(widget: LVGLUserWidgetWidget) {} + get isInsideUserWidget() { + return false; + } + endUserWidget() {} getWidgetIndex(object: LVGLWidget | Page) { @@ -319,7 +323,7 @@ export abstract class LVGLPageRuntime { //runtime.wasm._lvglDeleteObject(page._lvglObj); page._lvglObj = undefined; - page._lvglWidgetsIncludingUserWidgets.forEach( + page._lvglWidgets.forEach( widget => (widget._lvglObj = undefined) ); } @@ -615,7 +619,7 @@ export class LVGLPageEditorRuntime extends LVGLPageRuntime { try { // set all _lvglObj to undefined runInAction(() => { - this.page._lvglWidgetsIncludingUserWidgets.forEach( + this.page._lvglWidgets.forEach( widget => (widget._lvglObj = undefined) ); }); @@ -1140,6 +1144,10 @@ export class LVGLPageViewerRuntime extends LVGLPageRuntime { this.userWidgetsStack.push(widget); } + override get isInsideUserWidget() { + return this.userWidgetsStack.length > 0; + } + override endUserWidget() { this.userWidgetsStack.pop(); } @@ -1377,7 +1385,7 @@ export class LVGLStylesEditorRuntime extends LVGLPageRuntime { // set all _lvglObj to undefined runInAction(() => { - this.page._lvglWidgetsIncludingUserWidgets.forEach( + this.page._lvglWidgets.forEach( widget => (widget._lvglObj = undefined) ); }); @@ -1529,9 +1537,7 @@ function getObjects(page: Page) { const objects = []; objects.push(page._lvglObj!); - page._lvglWidgetsIncludingUserWidgets.forEach(widget => - objects.push(widget._lvglObj!) - ); + page._lvglWidgets.forEach(widget => objects.push(widget._lvglObj!)); return objects; } @@ -1548,7 +1554,7 @@ function setObjects( page._lvglObj = objects[index++]; - page._lvglWidgetsIncludingUserWidgets.forEach( + page._lvglWidgets.forEach( widget => (widget._lvglObj = objects[index++]) ); }); diff --git a/packages/project-editor/lvgl/widgets/Base.tsx b/packages/project-editor/lvgl/widgets/Base.tsx index d19d5011..84703ac0 100644 --- a/packages/project-editor/lvgl/widgets/Base.tsx +++ b/packages/project-editor/lvgl/widgets/Base.tsx @@ -1600,7 +1600,9 @@ export class LVGLWidget extends Widget { ) { const obj = this.lvglCreateObj(runtime, parentObj, customWidget); - runInAction(() => (this._lvglObj = obj)); + if (!runtime.isInsideUserWidget) { + runInAction(() => (this._lvglObj = obj)); + } if (this.group) { runtime.registerGroupWidget(this.group, this.groupIndex, obj); diff --git a/packages/project-editor/lvgl/widgets/Keyboard.tsx b/packages/project-editor/lvgl/widgets/Keyboard.tsx index 3a2ebe0d..8016d659 100644 --- a/packages/project-editor/lvgl/widgets/Keyboard.tsx +++ b/packages/project-editor/lvgl/widgets/Keyboard.tsx @@ -237,18 +237,18 @@ export class LVGLKeyboardWidget extends LVGLWidget { const textareaWidget = lvglIdentifier.widgets[0]; if (textareaWidget instanceof LVGLTextareaWidget) { + const keyboardWidgetIndex = runtime.getWidgetIndex(this); + const textareaWidgetIndex = runtime.getLvglObjectByName( textarea, runtime.userWidgetsStack ); - console.log(textarea, textareaWidgetIndex); - runtime.addPostCreateCallback(() => { setTimeout(() => { - if (this._lvglObj && runtime.isMounted) { + if (runtime.isMounted) { runtime.wasm._lvglSetKeyboardTextarea( - this._lvglObj, + keyboardWidgetIndex, textareaWidgetIndex ); } diff --git a/packages/project-editor/lvgl/widgets/UserWidget.tsx b/packages/project-editor/lvgl/widgets/UserWidget.tsx index 84db5031..eb913698 100644 --- a/packages/project-editor/lvgl/widgets/UserWidget.tsx +++ b/packages/project-editor/lvgl/widgets/UserWidget.tsx @@ -1,14 +1,13 @@ import React from "react"; import { observer } from "mobx-react"; -import { observable, makeObservable, computed, runInAction } from "mobx"; +import { observable, makeObservable, computed } from "mobx"; import { IMessage, MessageType, PropertyProps, PropertyType, - makeDerivedClassInfo, - setParent + makeDerivedClassInfo } from "project-editor/core/object"; import { @@ -28,13 +27,11 @@ import { COMPONENT_TYPE_LVGL_USER_WIDGET } from "project-editor/flow/components/ import { getComponentName } from "project-editor/flow/components/components-registry"; import { USER_WIDGET_ICON } from "project-editor/ui-components/icons"; import { - clipboardDataToObject, getAncestorOfType, getChildOfObject, getObjectPathAsString, getProjectStore, Message, - objectToClipboardData, propertyNotFoundMessage, propertyNotSetMessage, updateObject @@ -234,8 +231,7 @@ export class LVGLUserWidgetWidget extends LVGLWidget { makeObservable(this, { userWidgetPage: computed, - isCycleDetected: computed, - userWidgetPageCopy: computed({ keepAlive: true }) + isCycleDetected: computed }); } @@ -307,49 +303,6 @@ export class LVGLUserWidgetWidget extends LVGLWidget { return testForCycle(userWidgetPage); } - _userWidgetPageCopyIds: string[] = []; - - get userWidgetPageCopy(): Page | undefined { - const page = this.userWidgetPage; - - if (!page) { - return undefined; - } - - const project = ProjectEditor.getProject(page); - const projectStore = project._store; - - let userWidgetPageCopy: Page | undefined = undefined; - - // WORKAROUND: projectStore.lastRevisionStable is read to detect if the page was modified - projectStore.lastRevisionStable; - - // runInAction is needed to avoid observing copied page - runInAction(() => { - const idsBefore = new Set(projectStore.objects.keys()); - - userWidgetPageCopy = clipboardDataToObject( - projectStore, - objectToClipboardData(projectStore, page) - ).object as Page; - setParent(userWidgetPageCopy, project.userWidgets); - - for (const id of this._userWidgetPageCopyIds) { - projectStore.objects.delete(id); - } - this._userWidgetPageCopyIds = []; - for (const id of projectStore.objects.keys()) { - if (!idsBefore.has(id)) { - this._userWidgetPageCopyIds.push(id); - } - } - - userWidgetPageCopy._lvglUserWidgetOfPageCopy = this; - }); - - return userWidgetPageCopy; - } - open() { if (this.userWidgetPage) { getProjectStore(this).navigationStore.showObjects( @@ -434,9 +387,9 @@ export class LVGLUserWidgetWidget extends LVGLWidget { ): number { const widgetIndex = runtime.getWidgetIndex(this); - const userWidgetPageCopy = this.userWidgetPageCopy; + const userWidgetPage = this.userWidgetPage; - if (!userWidgetPageCopy || this.isCycleDetected) { + if (!userWidgetPage || this.isCycleDetected) { const rect = this.getLvglCreateRect(); return runtime.wasm._lvglCreateUserWidget( @@ -478,7 +431,7 @@ export class LVGLUserWidgetWidget extends LVGLWidget { runtime.beginUserWidget(this); - const obj = userWidgetPageCopy.lvglCreate(runtime, parentObj, { + const obj = userWidgetPage.lvglCreate(runtime, parentObj, { widgetIndex, left: rect.left, top: rect.top, diff --git a/resources/eez-framework-amalgamation/eez-flow.cpp b/resources/eez-framework-amalgamation/eez-flow.cpp index c29de08d..1e8399df 100644 --- a/resources/eez-framework-amalgamation/eez-flow.cpp +++ b/resources/eez-framework-amalgamation/eez-flow.cpp @@ -1,4 +1,4 @@ -/* Autogenerated on December 13, 2024 5:53:17 PM from eez-framework commit 7dcacae5b4b7936d36d1c7257ee51cc53e895925 */ +/* Autogenerated on December 14, 2024 11:41:16 AM from eez-framework commit 48ec9b6f2bcdc7677b3f9485f6e6dbc07fbad732 */ /* * eez-framework * @@ -4177,16 +4177,16 @@ void executeLVGLComponent(FlowState *flowState, unsigned componentIndex) { NAME = (lv_obj_t *)NAME##Value.getWidget(); \ } else if (NAME##Value.isString()) { \ const char *objectName = NAME##Value.getString(); \ - int32_t NAME##_WidgetIndex = getLvglObjectByNameHook(objectName); \ - if (NAME##_WidgetIndex == -1) { \ + int32_t widgetIndex = getLvglObjectByNameHook(objectName); \ + if (widgetIndex == -1) { \ throwError(flowState, componentIndex, FlowError::NotFoundInAction("Widget", objectName, actionName, actionIndex)); \ return; \ } \ - NAME = getLvglObjectFromIndexHook(flowState->lvglWidgetStartIndex + NAME##_WidgetIndex); \ + NAME = getLvglObjectFromIndexHook(flowState->lvglWidgetStartIndex + widgetIndex); \ } else { \ - int32_t NAME##_WidgetIndex = NAME##Value.getInt(); \ - for (FlowState *fs = flowState; fs; fs = fs->parentFlowState) NAME##_WidgetIndex += fs->lvglWidgetStartIndex; \ - NAME = getLvglObjectFromIndexHook(NAME##_WidgetIndex); \ + int32_t widgetIndex = NAME##Value.getInt(); \ + for (FlowState *fs = flowState; fs; fs = fs->parentFlowState) widgetIndex += fs->lvglWidgetStartIndex; \ + NAME = getLvglObjectFromIndexHook(widgetIndex); \ } \ if (!NAME) { \ throwError(flowState, componentIndex, FlowError::NullInAction("Widget", actionName, actionIndex)); \ diff --git a/resources/eez-framework-amalgamation/eez-flow.h b/resources/eez-framework-amalgamation/eez-flow.h index d196d52e..df2cb58a 100644 --- a/resources/eez-framework-amalgamation/eez-flow.h +++ b/resources/eez-framework-amalgamation/eez-flow.h @@ -1,4 +1,4 @@ -/* Autogenerated on December 13, 2024 5:53:17 PM from eez-framework commit 7dcacae5b4b7936d36d1c7257ee51cc53e895925 */ +/* Autogenerated on December 14, 2024 11:41:16 AM from eez-framework commit 48ec9b6f2bcdc7677b3f9485f6e6dbc07fbad732 */ /* * eez-framework * diff --git a/wasm/eez-framework b/wasm/eez-framework index 48ec9b6f..88de271b 160000 --- a/wasm/eez-framework +++ b/wasm/eez-framework @@ -1 +1 @@ -Subproject commit 48ec9b6f2bcdc7677b3f9485f6e6dbc07fbad732 +Subproject commit 88de271bf838c027275362c258e7c14f072e6aae diff --git a/wasm/lvgl-runtime/common/src/studio_api.cpp b/wasm/lvgl-runtime/common/src/studio_api.cpp index 75d0b4fe..ca4efb30 100644 --- a/wasm/lvgl-runtime/common/src/studio_api.cpp +++ b/wasm/lvgl-runtime/common/src/studio_api.cpp @@ -930,12 +930,17 @@ EM_PORT_API(void) lvglSetImgbuttonImageSrc(lv_obj_t *obj, lv_imgbtn_state_t stat lv_obj_update_layout(obj); } -EM_PORT_API(void) lvglSetKeyboardTextarea(lv_obj_t *obj, int32_t textareaIndex) { +EM_PORT_API(void) lvglSetKeyboardTextarea(int32_t keyboardIndex, int32_t textareaIndex) { + lv_obj_t *keyboard = getLvglObjectFromIndex(keyboardIndex); + if (!keyboard) { + return; + } lv_obj_t *textarea = getLvglObjectFromIndex(textareaIndex); - if (textarea) { - lv_keyboard_set_textarea(obj, textarea); - lv_obj_update_layout(obj); + if (!textarea) { + return; } + lv_keyboard_set_textarea(keyboard, textarea); + lv_obj_update_layout(keyboard); } #if LVGL_VERSION_MAJOR >= 9