From 1964dfe2ab0fa2d9dd672d1e0ee4d50ec6c5759d Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 8 May 2025 02:10:39 +0200 Subject: [PATCH] fix(xml): handle nested 'extends' handling with components --- src/others/xml/lv_xml.c | 4 +++- src/others/xml/lv_xml_component.c | 15 +++----------- src/others/xml/lv_xml_component_private.h | 2 +- src/others/xml/lv_xml_widget.c | 24 +++++++++++++++++++++++ src/others/xml/lv_xml_widget.h | 1 + 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/others/xml/lv_xml.c b/src/others/xml/lv_xml.c index 45c6317557..1d45933747 100644 --- a/src/others/xml/lv_xml.c +++ b/src/others/xml/lv_xml.c @@ -144,7 +144,8 @@ void * lv_xml_create_from_ctx(lv_obj_t * parent, lv_xml_component_ctx_t * parent state.item = state.view; if(attrs) { - ctx->root_widget->apply_cb(&state, attrs); + lv_widget_processor_t * proc = lv_xml_widget_get_extended_widget_processor(ctx->extends); + proc->apply_cb(&state, attrs); } lv_ll_clear(&state.parent_ll); @@ -610,4 +611,5 @@ static void view_end_element_handler(void * user_data, const char * name) } } + #endif /* LV_USE_XML */ diff --git a/src/others/xml/lv_xml_component.c b/src/others/xml/lv_xml_component.c index 473458104d..be2ce77dca 100644 --- a/src/others/xml/lv_xml_component.c +++ b/src/others/xml/lv_xml_component.c @@ -90,7 +90,8 @@ lv_obj_t * lv_xml_component_process(lv_xml_parser_state_t * state, const char * /* Apply the properties of the component, e.g. */ state->item = item; - ctx->root_widget->apply_cb(state, attrs); + lv_widget_processor_t * extended_proc = lv_xml_widget_get_extended_widget_processor(ctx->extends); + extended_proc->apply_cb(state, attrs); return item; } @@ -628,17 +629,7 @@ static void start_metadata_handler(void * user_data, const char * name, const ch const char * extends = lv_xml_get_value_of(attrs, "extends"); if(extends == NULL) extends = "lv_obj"; - state->ctx.root_widget = lv_xml_widget_get_processor(extends); - if(state->ctx.root_widget == NULL) { - lv_xml_component_ctx_t * extended_component = lv_xml_component_get_ctx(extends); - if(extended_component) { - state->ctx.root_widget = extended_component->root_widget; - } - else { - LV_LOG_WARN("The 'extend'ed widget is not found, using `lv_obj` as a fall back"); - state->ctx.root_widget = lv_xml_widget_get_processor("lv_obj"); - } - } + state->ctx.extends = lv_strdup(extends); } if(lv_streq(name, "widget")) state->ctx.is_widget = 1; diff --git a/src/others/xml/lv_xml_component_private.h b/src/others/xml/lv_xml_component_private.h index 1f53c4f57c..8737b4ccdc 100644 --- a/src/others/xml/lv_xml_component_private.h +++ b/src/others/xml/lv_xml_component_private.h @@ -38,7 +38,7 @@ struct _lv_xml_component_ctx_t { lv_ll_t image_ll; lv_ll_t event_ll; const char * view_def; - struct _lv_widget_processor_t * root_widget; + const char * extends; uint32_t is_widget : 1; /*1: not component but widget registered as a component for preview*/ struct _lv_xml_component_ctx_t * next; }; diff --git a/src/others/xml/lv_xml_widget.c b/src/others/xml/lv_xml_widget.c index b468038ddd..5c5e4fade5 100644 --- a/src/others/xml/lv_xml_widget.c +++ b/src/others/xml/lv_xml_widget.c @@ -70,6 +70,30 @@ lv_widget_processor_t * lv_xml_widget_get_processor(const char * name) return NULL; } +lv_widget_processor_t * lv_xml_widget_get_extended_widget_processor(const char * extends) +{ + lv_widget_processor_t * proc = NULL; + while(extends) { + proc = lv_xml_widget_get_processor(extends); + if(proc) break; + + lv_xml_component_ctx_t * extended_component = lv_xml_component_get_ctx(extends); + if(extended_component) { + extends = extended_component->extends; + } + else { + /*Not extending a known component or widget.*/ + break; + } + } + + if(proc == NULL) { + LV_LOG_WARN("The 'extend'ed widget is not found, using `lv_obj` as a fall back"); + proc = lv_xml_widget_get_processor("lv_obj"); + } + + return proc; +} /********************** * STATIC FUNCTIONS diff --git a/src/others/xml/lv_xml_widget.h b/src/others/xml/lv_xml_widget.h index a9305829c3..96690f0b5b 100644 --- a/src/others/xml/lv_xml_widget.h +++ b/src/others/xml/lv_xml_widget.h @@ -42,6 +42,7 @@ lv_result_t lv_xml_widget_register(const char * name, lv_xml_widget_create_cb_t lv_widget_processor_t * lv_xml_widget_get_processor(const char * name); +lv_widget_processor_t * lv_xml_widget_get_extended_widget_processor(const char * extends); /********************** * MACROS **********************/