fix(xml): handle nested 'extends' handling with components

This commit is contained in:
Gabor Kiss-Vamosi
2025-05-08 02:10:39 +02:00
committed by Liam Howatt
parent b23a2283dd
commit 1964dfe2ab
5 changed files with 32 additions and 14 deletions
+3 -1
View File
@@ -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 */
+3 -12
View File
@@ -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. <my_button x="20" styles="red"/> */
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;
+1 -1
View File
@@ -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;
};
+24
View File
@@ -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
+1
View File
@@ -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
**********************/