mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-18 00:25:17 +08:00
feat(xml): add subject and global/local scoping support
This commit is contained in:
@@ -57,15 +57,34 @@ A typical structure for a component library looks like this:
|
||||
Visibility
|
||||
**********
|
||||
|
||||
A component library can use images, fonts, components, widgets, etc., from other component libraries.
|
||||
It is the user's responsibility to avoid naming conflicts by prefixing names. For example, all
|
||||
data belonging to the LVGL core component library is prefixed by ``lv_`` (e.g., ``lv_label``, ``lv_montserrat_22``).
|
||||
The content of all ``globals.xml`` files is part of a common global scope, and
|
||||
any components, widgets, or screens can use data from there.
|
||||
|
||||
Styles, constants, and other data defined in the XML file of components, widgets, or screens
|
||||
are local to the given file.
|
||||
|
||||
In this sense, there are two namespaces:
|
||||
|
||||
1. **Local namespace** in the given XML file of components, widgets, and screens.
|
||||
2. **Global namespace** created from the data in all ``globals.xml`` files.
|
||||
|
||||
The referenced names are always checked first in the local namespace.
|
||||
If not found there, the global namespace is also checked.
|
||||
|
||||
The defined components, widgets, and screens are part of the global namespace, meaning
|
||||
there cannot be two ``mybutton`` components.
|
||||
|
||||
All data belonging to the LVGL core component library is prefixed by ``lv_``
|
||||
(e.g., ``lv_label``, ``lv_font_default``).
|
||||
|
||||
A custom component can be prefixed with ``watch_``, ``small_``, ``light_``, or
|
||||
anything else that the developer finds appropriate.
|
||||
|
||||
A custom component can be prefixed with ``watch_``, ``small_``, ``light_``, or anything else that the developer finds appropriate.
|
||||
LVGL's UI editor will show an error if there is a naming conflict.
|
||||
|
||||
globals.xml
|
||||
***********
|
||||
|
||||
``globals.xml``
|
||||
***************
|
||||
|
||||
A ``globals.xml`` file should be created in each component library.
|
||||
The definitions in it do not belong to any specific widget but are available throughout the entire UI, widgets, and all XML files.
|
||||
|
||||
@@ -4,4 +4,39 @@
|
||||
Subjects
|
||||
========
|
||||
|
||||
TODO
|
||||
T
|
||||
Subjects
|
||||
To connect values of the widget internally or to external data, subjects can be used. For example, an internally connected value could be a slider's value mapped to a label. Externally connected data could be the current number of users shown on a label.
|
||||
|
||||
To handle internal connections, local subjects can be created like this:
|
||||
|
||||
<subjects>
|
||||
<int name="a" value="20"/>
|
||||
<string name="b" value="Hello"/>
|
||||
<group name="a_and_b" value="a b"/>
|
||||
</subjects>
|
||||
|
||||
These subjects can be used in widget APIs like:
|
||||
|
||||
<view>
|
||||
<label bind_text="a 'Progress: %d'"/>
|
||||
</view>
|
||||
When generating code, the subjects are saved in the widget's data and are used like this:
|
||||
|
||||
lv_subject_init_int(&my_widget->subject_a, 20);
|
||||
lv_subject_init_string(&my_widget->subject_b, "Hello");
|
||||
|
||||
my_widget->subject_a_and_b_list = lv_malloc(sizeof(lv_subject_t *) * 2);
|
||||
my_widget->subject_a_and_b_list[0] = &my_widget->subject_a;
|
||||
my_widget->subject_a_and_b_list[1] = &my_widget->subject_b;
|
||||
lv_subject_init_group(&my_widget->subject_a_and_b, my_widget->subject_a_and_b_list);
|
||||
If the connection is more complex and not supported out of the box, it can be handled from code.
|
||||
|
||||
External subjects are defined in the API of the widget:
|
||||
|
||||
<api>
|
||||
<prop name="bind_value" help="">
|
||||
<param name="subject" type="subject" help=""/>
|
||||
<param name="max_value" type="int" help="Just another parameter, e.g., to limit the value"/>
|
||||
</prop>
|
||||
</api>
|
||||
|
||||
+172
-34
@@ -33,6 +33,8 @@
|
||||
#include "parsers/lv_xml_scale_parser.h"
|
||||
#include "parsers/lv_xml_buttonmatrix_parser.h"
|
||||
#include "parsers/lv_xml_spangroup_parser.h"
|
||||
#include "parsers/lv_xml_textarea_parser.h"
|
||||
#include "parsers/lv_xml_keyboard_parser.h"
|
||||
#include "parsers/lv_xml_event_parser.h"
|
||||
#include "../../libs/expat/expat.h"
|
||||
#include "../../draw/lv_draw_image.h"
|
||||
@@ -54,9 +56,6 @@ static void view_end_element_handler(void * user_data, const char * name);
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_ll_t font_ll;
|
||||
static lv_ll_t image_ll;
|
||||
static lv_ll_t event_cb_ll;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@@ -68,14 +67,10 @@ static lv_ll_t event_cb_ll;
|
||||
|
||||
void lv_xml_init(void)
|
||||
{
|
||||
lv_ll_init(&font_ll, sizeof(lv_xml_font_t));
|
||||
lv_ll_init(&image_ll, sizeof(lv_xml_image_t));
|
||||
lv_ll_init(&event_cb_ll, sizeof(lv_xml_event_cb_t));
|
||||
|
||||
lv_xml_register_font("lv_font_default", lv_font_default);
|
||||
|
||||
lv_xml_component_init();
|
||||
|
||||
lv_xml_register_font(NULL, "lv_font_default", lv_font_default);
|
||||
|
||||
lv_xml_widget_register("lv_obj", lv_xml_obj_create, lv_xml_obj_apply);
|
||||
lv_xml_widget_register("lv_button", lv_xml_button_create, lv_xml_button_apply);
|
||||
lv_xml_widget_register("lv_label", lv_xml_label_create, lv_xml_label_apply);
|
||||
@@ -100,6 +95,8 @@ void lv_xml_init(void)
|
||||
lv_xml_widget_register("lv_spangroup", lv_xml_spangroup_create, lv_xml_spangroup_apply);
|
||||
lv_xml_widget_register("lv_spangroup-span", lv_xml_spangroup_span_create, lv_xml_spangroup_span_apply);
|
||||
lv_xml_widget_register("lv_buttonmatrix", lv_xml_buttonmatrix_create, lv_xml_buttonmatrix_apply);
|
||||
lv_xml_widget_register("lv_textarea", lv_xml_textarea_create, lv_xml_textarea_apply);
|
||||
lv_xml_widget_register("lv_keyboard", lv_xml_keyboard_create, lv_xml_keyboard_apply);
|
||||
|
||||
lv_xml_widget_register("lv_event-call_function", lv_xml_event_call_function_create, lv_xml_event_call_function_apply);
|
||||
}
|
||||
@@ -153,6 +150,7 @@ void * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs)
|
||||
lv_xml_parser_state_t state;
|
||||
lv_xml_parser_state_init(&state);
|
||||
state.parent = parent;
|
||||
state.ctx.name = "";
|
||||
state.item = p->create_cb(&state, attrs);
|
||||
if(attrs) {
|
||||
p->apply_cb(&state, attrs);
|
||||
@@ -172,29 +170,137 @@ void * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs)
|
||||
}
|
||||
|
||||
|
||||
lv_result_t lv_xml_register_font(const char * name, const lv_font_t * font)
|
||||
lv_result_t lv_xml_register_font(lv_xml_component_ctx_t * ctx, const char * name, const lv_font_t * font)
|
||||
{
|
||||
lv_xml_font_t * f = lv_ll_ins_head(&font_ll);
|
||||
if(ctx == NULL) ctx = lv_xml_component_get_ctx("globals");
|
||||
if(ctx == NULL) {
|
||||
LV_LOG_WARN("No component found to register font `%s`", name);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
lv_xml_font_t * f = lv_ll_ins_head(&ctx->font_ll);
|
||||
f->name = lv_strdup(name);
|
||||
f->font = font;
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
const lv_font_t * lv_xml_get_font(const char * name)
|
||||
const lv_font_t * lv_xml_get_font(lv_xml_component_ctx_t * ctx, const char * name)
|
||||
{
|
||||
lv_xml_font_t * f;
|
||||
LV_LL_READ(&font_ll, f) {
|
||||
if(lv_streq(f->name, name)) return f->font;
|
||||
if(ctx) {
|
||||
LV_LL_READ(&ctx->font_ll, f) {
|
||||
if(lv_streq(f->name, name)) return f->font;
|
||||
}
|
||||
}
|
||||
|
||||
/*If not found in the component check the global space*/
|
||||
if(!lv_streq(ctx->name, "globals")) {
|
||||
ctx = lv_xml_component_get_ctx("globals");
|
||||
if(ctx) {
|
||||
LV_LL_READ(&ctx->font_ll, f) {
|
||||
if(lv_streq(f->name, name)) return f->font;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LV_LOG_WARN("No font was found with name \"%s\". Using LV_FONT_DEFAULT instead.", name);
|
||||
return LV_FONT_DEFAULT;
|
||||
return lv_font_get_default();
|
||||
}
|
||||
|
||||
lv_result_t lv_xml_register_image(const char * name, const void * src)
|
||||
lv_result_t lv_xml_register_subject(lv_xml_component_ctx_t * ctx, const char * name, lv_subject_t * subject)
|
||||
{
|
||||
lv_xml_image_t * img = lv_ll_ins_head(&image_ll);
|
||||
if(ctx == NULL) ctx = lv_xml_component_get_ctx("globals");
|
||||
if(ctx == NULL) {
|
||||
LV_LOG_WARN("No component found to register subject `%s`", name);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
lv_xml_subject_t * s = lv_ll_ins_head(&ctx->subjects_ll);
|
||||
s->name = lv_strdup(name);
|
||||
s->subject = subject;
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_subject_t * lv_xml_get_subject(lv_xml_component_ctx_t * ctx, const char * name)
|
||||
{
|
||||
lv_xml_subject_t * s;
|
||||
if(ctx) {
|
||||
LV_LL_READ(&ctx->subjects_ll, s) {
|
||||
if(lv_streq(s->name, name)) return s->subject;
|
||||
}
|
||||
}
|
||||
|
||||
/*If not found in the component check the global space*/
|
||||
if(!lv_streq(ctx->name, "globals")) {
|
||||
ctx = lv_xml_component_get_ctx("globals");
|
||||
if(ctx) {
|
||||
LV_LL_READ(&ctx->subjects_ll, s) {
|
||||
if(lv_streq(s->name, name)) return s->subject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LV_LOG_WARN("No subject was found with name \"%s\".", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_result_t lv_xml_register_const(lv_xml_component_ctx_t * ctx, const char * name, const char * value)
|
||||
{
|
||||
if(ctx == NULL) ctx = lv_xml_component_get_ctx("globals");
|
||||
if(ctx == NULL) {
|
||||
LV_LOG_WARN("No component found to register constant `%s`", name);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
lv_xml_const_t * cnst;
|
||||
cnst = lv_ll_ins_head(&ctx->const_ll);
|
||||
|
||||
cnst->name = lv_strdup(name);
|
||||
cnst->value = lv_strdup(value);
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
const char * lv_xml_get_const(lv_xml_component_ctx_t * ctx, const char * name)
|
||||
{
|
||||
|
||||
if(ctx == NULL) ctx = lv_xml_component_get_ctx("globals");
|
||||
if(ctx == NULL) return LV_RESULT_INVALID;
|
||||
|
||||
lv_xml_const_t * cnst;
|
||||
if(ctx) {
|
||||
LV_LL_READ(&ctx->const_ll, cnst) {
|
||||
if(lv_streq(cnst->name, name)) return cnst->value;
|
||||
}
|
||||
}
|
||||
|
||||
/*If not found in the component check the global space*/
|
||||
if(!lv_streq(ctx->name, "globals")) {
|
||||
ctx = lv_xml_component_get_ctx("globals");
|
||||
if(ctx) {
|
||||
LV_LL_READ(&ctx->const_ll, cnst) {
|
||||
if(lv_streq(cnst->name, name)) return cnst->value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LV_LOG_WARN("No constant was found with name \"%s\".", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
lv_result_t lv_xml_register_image(lv_xml_component_ctx_t * ctx, const char * name, const void * src)
|
||||
{
|
||||
if(ctx == NULL) ctx = lv_xml_component_get_ctx("globals");
|
||||
if(ctx == NULL) {
|
||||
LV_LOG_WARN("No component found to register image `%s`", name);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
lv_xml_image_t * img = lv_ll_ins_head(&ctx->image_ll);
|
||||
img->name = lv_strdup(name);
|
||||
if(lv_image_src_get_type(src) == LV_IMAGE_SRC_FILE) {
|
||||
img->src = lv_strdup(src);
|
||||
@@ -206,20 +312,41 @@ lv_result_t lv_xml_register_image(const char * name, const void * src)
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
const void * lv_xml_get_image(const char * name)
|
||||
const void * lv_xml_get_image(lv_xml_component_ctx_t * ctx, const char * name)
|
||||
{
|
||||
if(ctx == NULL) ctx = lv_xml_component_get_ctx("globals");
|
||||
if(ctx == NULL) return LV_RESULT_INVALID;
|
||||
|
||||
lv_xml_image_t * img;
|
||||
LV_LL_READ(&image_ll, img) {
|
||||
if(lv_streq(img->name, name)) return img->src;
|
||||
if(ctx) {
|
||||
LV_LL_READ(&ctx->image_ll, img) {
|
||||
if(lv_streq(img->name, name)) return img->src;
|
||||
}
|
||||
}
|
||||
|
||||
/*If not found in the component check the global space*/
|
||||
if(!lv_streq(ctx->name, "globals")) {
|
||||
ctx = lv_xml_component_get_ctx("globals");
|
||||
if(ctx) {
|
||||
LV_LL_READ(&ctx->image_ll, img) {
|
||||
if(lv_streq(img->name, name)) return img->src;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LV_LOG_WARN("No image was found with name \"%s\"", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_result_t lv_xml_register_event_cb(const char * name, lv_event_cb_t cb)
|
||||
lv_result_t lv_xml_register_event_cb(lv_xml_component_ctx_t * ctx, const char * name, lv_event_cb_t cb)
|
||||
{
|
||||
lv_xml_event_cb_t * e = lv_ll_ins_head(&event_cb_ll);
|
||||
if(ctx == NULL) ctx = lv_xml_component_get_ctx("globals");
|
||||
if(ctx == NULL) {
|
||||
LV_LOG_WARN("No component found to register event `%s`", name);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
lv_xml_event_cb_t * e = lv_ll_ins_head(&ctx->event_ll);
|
||||
e->name = lv_strdup(name);
|
||||
e->cb = cb;
|
||||
|
||||
@@ -227,14 +354,29 @@ lv_result_t lv_xml_register_event_cb(const char * name, lv_event_cb_t cb)
|
||||
}
|
||||
|
||||
|
||||
lv_event_cb_t lv_xml_get_event_cb(const char * name)
|
||||
lv_event_cb_t lv_xml_get_event_cb(lv_xml_component_ctx_t * ctx, const char * name)
|
||||
{
|
||||
if(ctx == NULL) ctx = lv_xml_component_get_ctx("globals");
|
||||
if(ctx == NULL) return LV_RESULT_INVALID;
|
||||
|
||||
lv_xml_event_cb_t * e;
|
||||
LV_LL_READ(&event_cb_ll, e) {
|
||||
if(lv_streq(e->name, name)) return e->cb;
|
||||
if(ctx) {
|
||||
LV_LL_READ(&ctx->event_ll, e) {
|
||||
if(lv_streq(e->name, name)) return e->cb;
|
||||
}
|
||||
}
|
||||
|
||||
LV_LOG_WARN("No event_cb was found with name \"%s\"", name);
|
||||
/*If not found in the component check the global space*/
|
||||
if(!lv_streq(ctx->name, "globals")) {
|
||||
ctx = lv_xml_component_get_ctx("globals");
|
||||
if(ctx) {
|
||||
LV_LL_READ(&ctx->event_ll, e) {
|
||||
if(lv_streq(e->name, name)) return e->cb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LV_LOG_WARN("No event was found with name \"%s\"", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -315,16 +457,12 @@ static void resolve_consts(const char ** item_attrs, lv_xml_component_ctx_t * ct
|
||||
if(value[0] == '#') {
|
||||
const char * value_clean = &value[1];
|
||||
|
||||
lv_xml_const_t * c;
|
||||
LV_LL_READ(&ctx->const_ll, c) {
|
||||
if(lv_streq(c->name, value_clean)) {
|
||||
item_attrs[i + 1] = c->value;
|
||||
break;
|
||||
}
|
||||
const char * const_value = lv_xml_get_const(ctx, value_clean);
|
||||
if(const_value) {
|
||||
item_attrs[i + 1] = const_value;
|
||||
}
|
||||
|
||||
/*If the const attribute is not provide don't set it*/
|
||||
if(c == NULL) {
|
||||
else {
|
||||
item_attrs[i] = "";
|
||||
item_attrs[i + 1] = "";
|
||||
}
|
||||
|
||||
+29
-6
@@ -15,6 +15,8 @@ extern "C" {
|
||||
*********************/
|
||||
#include "../../misc/lv_types.h"
|
||||
#include "../../misc/lv_event.h"
|
||||
#include "../../others/observer/lv_observer.h"
|
||||
|
||||
#if LV_USE_XML
|
||||
|
||||
/*********************
|
||||
@@ -36,18 +38,39 @@ void * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs);
|
||||
void * lv_xml_create_from_ctx(lv_obj_t * parent, lv_xml_component_ctx_t * parent_ctx, lv_xml_component_ctx_t * ctx,
|
||||
const char ** attrs);
|
||||
|
||||
lv_result_t lv_xml_register_font(const char * name, const lv_font_t * font);
|
||||
lv_result_t lv_xml_register_font(lv_xml_component_ctx_t * ctx, const char * name, const lv_font_t * font);
|
||||
|
||||
const lv_font_t * lv_xml_get_font(const char * name);
|
||||
const lv_font_t * lv_xml_get_font(lv_xml_component_ctx_t * ctx, const char * name);
|
||||
|
||||
lv_result_t lv_xml_register_image(const char * name, const void * src);
|
||||
lv_result_t lv_xml_register_image(lv_xml_component_ctx_t * ctx, const char * name, const void * src);
|
||||
|
||||
const void * lv_xml_get_image(const char * name);
|
||||
const void * lv_xml_get_image(lv_xml_component_ctx_t * ctx, const char * name);
|
||||
|
||||
/**
|
||||
* Map globally available subject name to an actual subject variable
|
||||
* @param name name of the subject
|
||||
* @param subject pointer to a subject
|
||||
* @return `LV_RESULT_OK`: success
|
||||
*/
|
||||
lv_result_t lv_xml_register_subject(lv_xml_component_ctx_t * ctx, const char * name, lv_subject_t * subject);
|
||||
|
||||
lv_result_t lv_xml_register_event_cb(const char * name, lv_event_cb_t cb);
|
||||
/**
|
||||
* Get a subject by name.
|
||||
* @param ctx If specified start searching in that component's subject list,
|
||||
* and if not found search in the global space.
|
||||
* If `NULL` search in global space immediately.
|
||||
* @param name Name of the subject to find.
|
||||
* @return Pointer to the subject or NULL if not found.
|
||||
*/
|
||||
lv_subject_t * lv_xml_get_subject(lv_xml_component_ctx_t * ctx, const char * name);
|
||||
|
||||
lv_event_cb_t lv_xml_get_event_cb(const char * name);
|
||||
lv_result_t lv_xml_register_const(lv_xml_component_ctx_t * ctx, const char * name, const char * value);
|
||||
|
||||
const char * lv_xml_get_const(lv_xml_component_ctx_t * ctx, const char * name);
|
||||
|
||||
lv_result_t lv_xml_register_event_cb(lv_xml_component_ctx_t * ctx, const char * name, lv_event_cb_t cb);
|
||||
|
||||
lv_event_cb_t lv_xml_get_event_cb(lv_xml_component_ctx_t * ctx, const char * name);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -54,6 +54,24 @@ static lv_ll_t component_ctx_ll;
|
||||
void lv_xml_component_init(void)
|
||||
{
|
||||
lv_ll_init(&component_ctx_ll, sizeof(lv_xml_component_ctx_t));
|
||||
|
||||
lv_xml_component_ctx_t * global_ctx = lv_ll_ins_head(&component_ctx_ll);
|
||||
lv_memzero(global_ctx, sizeof(lv_xml_component_ctx_t));
|
||||
lv_xml_component_ctx_init(global_ctx);
|
||||
global_ctx->name = lv_strdup("globals");
|
||||
|
||||
}
|
||||
|
||||
void lv_xml_component_ctx_init(lv_xml_component_ctx_t * ctx)
|
||||
{
|
||||
lv_ll_init(&ctx->style_ll, sizeof(lv_xml_style_t));
|
||||
lv_ll_init(&ctx->const_ll, sizeof(lv_xml_const_t));
|
||||
lv_ll_init(&ctx->param_ll, sizeof(lv_xml_param_t));
|
||||
lv_ll_init(&ctx->gradient_ll, sizeof(lv_xml_grad_t));
|
||||
lv_ll_init(&ctx->subjects_ll, sizeof(lv_xml_subject_t));
|
||||
lv_ll_init(&ctx->event_ll, sizeof(lv_xml_event_cb_t));
|
||||
lv_ll_init(&ctx->image_ll, sizeof(lv_xml_image_t));
|
||||
lv_ll_init(&ctx->font_ll, sizeof(lv_xml_font_t));
|
||||
}
|
||||
|
||||
|
||||
@@ -86,10 +104,19 @@ lv_xml_component_ctx_t * lv_xml_component_get_ctx(const char * component_name)
|
||||
|
||||
lv_result_t lv_xml_component_register_from_data(const char * name, const char * xml_def)
|
||||
{
|
||||
bool globals = false;
|
||||
if(lv_streq(name, "globals")) globals = true;
|
||||
|
||||
/* Create a temporary parser state to extract styles/params/consts */
|
||||
lv_xml_parser_state_t state;
|
||||
lv_xml_parser_state_init(&state);
|
||||
state.ctx.name = name;
|
||||
if(globals) {
|
||||
lv_xml_component_ctx_t * global_ctx = lv_xml_component_get_ctx("globals");
|
||||
state.ctx = *global_ctx;
|
||||
}
|
||||
else {
|
||||
lv_xml_parser_state_init(&state);
|
||||
state.ctx.name = name;
|
||||
}
|
||||
|
||||
/* Parse the XML to extract metadata */
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
@@ -106,19 +133,26 @@ lv_result_t lv_xml_component_register_from_data(const char * name, const char *
|
||||
|
||||
XML_ParserFree(parser);
|
||||
|
||||
/* Copy extracted metadata to component processor */
|
||||
lv_xml_component_ctx_t * ctx = lv_ll_ins_head(&component_ctx_ll);
|
||||
lv_memzero(ctx, sizeof(lv_xml_component_ctx_t));
|
||||
lv_memcpy(ctx, &state.ctx, sizeof(lv_xml_component_ctx_t));
|
||||
|
||||
/* Extract view content directly instead of using XML parser */
|
||||
ctx->view_def = extract_view_content(xml_def);
|
||||
ctx->name = lv_strdup(name);
|
||||
if(!ctx->view_def) {
|
||||
LV_LOG_WARN("Failed to extract view content");
|
||||
/* Clean up and return error */
|
||||
lv_free(ctx);
|
||||
return LV_RESULT_INVALID;
|
||||
/* Copy extracted metadata to component processor */
|
||||
if(globals) {
|
||||
lv_xml_component_ctx_t * global_ctx = lv_xml_component_get_ctx("globals");
|
||||
lv_memcpy(global_ctx, &state.ctx, sizeof(lv_xml_component_ctx_t));
|
||||
}
|
||||
else {
|
||||
lv_xml_component_ctx_t * ctx = lv_ll_ins_head(&component_ctx_ll);
|
||||
lv_memzero(ctx, sizeof(lv_xml_component_ctx_t));
|
||||
lv_memcpy(ctx, &state.ctx, sizeof(lv_xml_component_ctx_t));
|
||||
|
||||
/* Extract view content directly instead of using XML parser */
|
||||
ctx->view_def = extract_view_content(xml_def);
|
||||
ctx->name = lv_strdup(name);
|
||||
if(!ctx->view_def) {
|
||||
LV_LOG_WARN("Failed to extract view content");
|
||||
/* Clean up and return error */
|
||||
lv_free(ctx);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
@@ -223,6 +257,17 @@ lv_result_t lv_xml_component_unregister(const char * name)
|
||||
}
|
||||
lv_ll_clear(&ctx->gradient_ll);
|
||||
|
||||
lv_xml_subject_t * subject;
|
||||
LV_LL_READ(&ctx->subjects_ll, subject) {
|
||||
lv_free((char *)subject->name);
|
||||
if(subject->subject->type == LV_SUBJECT_TYPE_STRING) {
|
||||
lv_free((char *)subject->subject->prev_value.pointer);
|
||||
lv_free((char *)subject->subject->value.pointer);
|
||||
}
|
||||
lv_free(subject->subject);
|
||||
}
|
||||
lv_ll_clear(&ctx->subjects_ll);
|
||||
|
||||
lv_free(ctx);
|
||||
|
||||
return LV_RESULT_OK;
|
||||
@@ -246,14 +291,40 @@ static void process_const_element(lv_xml_parser_state_t * state, const char ** a
|
||||
return;
|
||||
}
|
||||
|
||||
lv_xml_const_t * cnst = lv_ll_ins_tail(&state->ctx.const_ll);
|
||||
cnst->name = lv_strdup(name);
|
||||
cnst->value = lv_strdup(value);
|
||||
lv_xml_register_const(&state->ctx, name, value);
|
||||
}
|
||||
|
||||
static void process_subject_element(lv_xml_parser_state_t * state, const char * type, const char ** attrs)
|
||||
{
|
||||
const char * name = lv_xml_get_value_of(attrs, "name");
|
||||
const char * value = lv_xml_get_value_of(attrs, "value");
|
||||
|
||||
if(name == NULL) {
|
||||
LV_LOG_WARN("'name' is missing from a subject");
|
||||
return;
|
||||
}
|
||||
if(value == NULL) {
|
||||
LV_LOG_WARN("'value' is missing from a subject");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_subject_t * subject = lv_malloc(sizeof(lv_subject_t));
|
||||
|
||||
|
||||
if(lv_streq(type, "int")) lv_subject_init_int(subject, lv_xml_atoi(value));
|
||||
else if(lv_streq(type, "color")) lv_subject_init_color(subject, lv_xml_to_color(value));
|
||||
else if(lv_streq(type, "string")) {
|
||||
/*Simple solution for now. Will be improved later*/
|
||||
char * buf_prev = lv_malloc(256);
|
||||
char * buf_act = lv_malloc(256);
|
||||
lv_subject_init_string(subject, buf_act, buf_prev, 256, value);
|
||||
}
|
||||
|
||||
lv_xml_register_subject(&state->ctx, name, subject);
|
||||
}
|
||||
|
||||
static void process_grad_element(lv_xml_parser_state_t * state, const char * tag_name, const char ** attrs)
|
||||
{
|
||||
|
||||
lv_xml_grad_t * grad = lv_ll_ins_tail(&state->ctx.gradient_ll);
|
||||
grad->name = lv_strdup(lv_xml_get_value_of(attrs, "name"));
|
||||
lv_grad_dsc_t * dsc = &grad->grad_dsc;
|
||||
@@ -470,6 +541,11 @@ static void start_metadata_handler(void * user_data, const char * name, const ch
|
||||
lv_xml_style_register(&state->ctx, attrs);
|
||||
break;
|
||||
|
||||
case LV_XML_PARSER_SECTION_SUBJECTS:
|
||||
if(old_section != state->section) return; /*Ignore the section opening, e.g. <subjects>*/
|
||||
process_subject_element(state, name, attrs);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ extern "C" {
|
||||
#include "lv_xml_utils.h"
|
||||
#include "../../misc/lv_ll.h"
|
||||
#include "../../misc/lv_style.h"
|
||||
#include "../../others/observer/lv_observer.h"
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@@ -32,6 +33,10 @@ struct _lv_xml_component_ctx_t {
|
||||
lv_ll_t const_ll;
|
||||
lv_ll_t param_ll;
|
||||
lv_ll_t gradient_ll;
|
||||
lv_ll_t subjects_ll;
|
||||
lv_ll_t font_ll;
|
||||
lv_ll_t image_ll;
|
||||
lv_ll_t event_ll;
|
||||
const char * view_def;
|
||||
struct _lv_widget_processor_t * root_widget;
|
||||
uint32_t is_widget : 1; /*1: not component but widget registered as a component for preview*/
|
||||
@@ -43,6 +48,11 @@ typedef struct {
|
||||
const char * value;
|
||||
} lv_xml_const_t;
|
||||
|
||||
typedef struct {
|
||||
const char * name;
|
||||
lv_subject_t * subject;
|
||||
} lv_xml_subject_t;
|
||||
|
||||
typedef struct {
|
||||
const char * name;
|
||||
const char * def;
|
||||
@@ -63,6 +73,12 @@ typedef struct {
|
||||
*/
|
||||
void lv_xml_component_init(void);
|
||||
|
||||
/**
|
||||
* Initialize the linked lists of a component context
|
||||
* @param ctx pointer to a component contexts
|
||||
*/
|
||||
void lv_xml_component_ctx_init(lv_xml_component_ctx_t * ctx);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -42,11 +42,8 @@
|
||||
void lv_xml_parser_state_init(lv_xml_parser_state_t * state)
|
||||
{
|
||||
lv_memzero(state, sizeof(lv_xml_parser_state_t));
|
||||
lv_ll_init(&state->ctx.style_ll, sizeof(lv_xml_style_t));
|
||||
lv_ll_init(&state->ctx.const_ll, sizeof(lv_xml_const_t));
|
||||
lv_ll_init(&state->ctx.param_ll, sizeof(lv_xml_param_t));
|
||||
lv_ll_init(&state->ctx.gradient_ll, sizeof(lv_xml_grad_t));
|
||||
lv_ll_init(&state->parent_ll, sizeof(lv_obj_t *));
|
||||
lv_xml_component_ctx_init(&state->ctx);
|
||||
}
|
||||
|
||||
void lv_xml_parser_start_section(lv_xml_parser_state_t * state, const char * name)
|
||||
@@ -72,6 +69,10 @@ void lv_xml_parser_start_section(lv_xml_parser_state_t * state, const char * nam
|
||||
state->section = LV_XML_PARSER_SECTION_STYLES;
|
||||
return;
|
||||
}
|
||||
else if(lv_streq(name, "subjects")) {
|
||||
state->section = LV_XML_PARSER_SECTION_SUBJECTS;
|
||||
return;
|
||||
}
|
||||
else if(lv_streq(name, "view")) {
|
||||
state->section = LV_XML_PARSER_SECTION_VIEW;
|
||||
return;
|
||||
|
||||
@@ -35,6 +35,7 @@ typedef enum {
|
||||
LV_XML_PARSER_SECTION_GRAD,
|
||||
LV_XML_PARSER_SECTION_GRAD_STOP,
|
||||
LV_XML_PARSER_SECTION_STYLES,
|
||||
LV_XML_PARSER_SECTION_SUBJECTS,
|
||||
LV_XML_PARSER_SECTION_VIEW
|
||||
} lv_xml_parser_section_t;
|
||||
|
||||
|
||||
@@ -76,14 +76,19 @@ lv_part_t lv_xml_style_part_to_enum(const char * txt)
|
||||
return 0; /*Return 0 in lack of a better option. */
|
||||
}
|
||||
|
||||
void lv_xml_style_register(lv_xml_component_ctx_t * ctx, const char ** attrs)
|
||||
lv_result_t lv_xml_style_register(lv_xml_component_ctx_t * ctx, const char ** attrs)
|
||||
{
|
||||
const char * style_name = lv_xml_get_value_of(attrs, "name");
|
||||
if(style_name == NULL) {
|
||||
LV_LOG_WARN("'name' is missing from a style");
|
||||
return;
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
if(ctx == NULL) ctx = lv_xml_component_get_ctx("globals");
|
||||
if(ctx == NULL) return LV_RESULT_INVALID;
|
||||
|
||||
lv_xml_style_t * xml_style = lv_ll_ins_tail(&ctx->style_ll);
|
||||
|
||||
lv_style_t * style = &xml_style->style;
|
||||
lv_style_init(style);
|
||||
xml_style->name = lv_strdup(style_name);
|
||||
@@ -146,7 +151,7 @@ void lv_xml_style_register(lv_xml_component_ctx_t * ctx, const char ** attrs)
|
||||
else SET_STYLE_IF(bg_grad_stop, lv_xml_atoi(value));
|
||||
else SET_STYLE_IF(bg_grad, lv_xml_component_get_grad(ctx, value));
|
||||
|
||||
else SET_STYLE_IF(bg_image_src, lv_xml_get_image(value));
|
||||
else SET_STYLE_IF(bg_image_src, lv_xml_get_image(ctx, value));
|
||||
else SET_STYLE_IF(bg_image_tiled, lv_xml_to_bool(value));
|
||||
else SET_STYLE_IF(bg_image_recolor, lv_xml_to_color(value));
|
||||
else SET_STYLE_IF(bg_image_recolor_opa, lv_xml_to_opa(value));
|
||||
@@ -170,7 +175,7 @@ void lv_xml_style_register(lv_xml_component_ctx_t * ctx, const char ** attrs)
|
||||
else SET_STYLE_IF(shadow_opa, lv_xml_to_opa(value));
|
||||
|
||||
else SET_STYLE_IF(text_color, lv_xml_to_color(value));
|
||||
else SET_STYLE_IF(text_font, lv_xml_get_font(value));
|
||||
else SET_STYLE_IF(text_font, lv_xml_get_font(ctx, value));
|
||||
else SET_STYLE_IF(text_opa, lv_xml_to_opa(value));
|
||||
else SET_STYLE_IF(text_align, lv_xml_text_align_to_enum(value));
|
||||
else SET_STYLE_IF(text_letter_space, lv_xml_atoi(value));
|
||||
@@ -192,7 +197,7 @@ void lv_xml_style_register(lv_xml_component_ctx_t * ctx, const char ** attrs)
|
||||
else SET_STYLE_IF(arc_opa, lv_xml_to_opa(value));
|
||||
else SET_STYLE_IF(arc_width, lv_xml_atoi(value));
|
||||
else SET_STYLE_IF(arc_rounded, lv_xml_to_bool(value));
|
||||
else SET_STYLE_IF(arc_image_src, lv_xml_get_image(value));
|
||||
else SET_STYLE_IF(arc_image_src, lv_xml_get_image(ctx, value));
|
||||
|
||||
else SET_STYLE_IF(opa, lv_xml_to_opa(value));
|
||||
else SET_STYLE_IF(opa_layered, lv_xml_to_opa(value));
|
||||
@@ -210,7 +215,7 @@ void lv_xml_style_register(lv_xml_component_ctx_t * ctx, const char ** attrs)
|
||||
else SET_STYLE_IF(transform_pivot_x, lv_xml_atoi(value));
|
||||
else SET_STYLE_IF(transform_pivot_y, lv_xml_atoi(value));
|
||||
else SET_STYLE_IF(transform_skew_x, lv_xml_atoi(value));
|
||||
else SET_STYLE_IF(bitmap_mask_src, lv_xml_get_image(value));
|
||||
else SET_STYLE_IF(bitmap_mask_src, lv_xml_get_image(ctx, value));
|
||||
else SET_STYLE_IF(rotary_sensitivity, lv_xml_atoi(value));
|
||||
|
||||
else SET_STYLE_IF(layout, lv_xml_layout_to_enum(value));
|
||||
@@ -235,6 +240,8 @@ void lv_xml_style_register(lv_xml_component_ctx_t * ctx, const char ** attrs)
|
||||
LV_LOG_WARN("%s style property is not supported", name);
|
||||
}
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
const char * lv_xml_style_string_process(char * txt, lv_style_selector_t * selector)
|
||||
@@ -313,6 +320,16 @@ lv_xml_style_t * lv_xml_get_style_by_name(lv_xml_component_ctx_t * ctx, const ch
|
||||
if(lv_streq(xml_style->name, style_name)) return xml_style;
|
||||
}
|
||||
|
||||
/*If not found in the component check the global space*/
|
||||
if(!lv_streq(ctx->name, "globals")) {
|
||||
ctx = lv_xml_component_get_ctx("globals");
|
||||
if(ctx) {
|
||||
LV_LL_READ(&ctx->style_ll, xml_style) {
|
||||
if(lv_streq(xml_style->name, style_name)) return xml_style;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LV_LOG_WARN("No style found with %s name", style_name_raw);
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -38,7 +38,7 @@ typedef struct _lv_xml_style_t {
|
||||
* @param ctx add styles here. (Constants should be already added as style properties might use them)
|
||||
* @param attrs list of attribute names and values
|
||||
*/
|
||||
void lv_xml_style_register(lv_xml_component_ctx_t * ctx, const char ** attrs);
|
||||
lv_result_t lv_xml_style_register(lv_xml_component_ctx_t * ctx, const char ** attrs);
|
||||
|
||||
/**
|
||||
* Add the styles to an object. Handles multiple styles and selectors too.
|
||||
|
||||
@@ -58,7 +58,7 @@ void lv_xml_dropdown_apply(lv_xml_parser_state_t * state, const char ** attrs)
|
||||
if(lv_streq("options", name)) lv_dropdown_set_options(item, value);
|
||||
if(lv_streq("text", name)) lv_dropdown_set_text(item, value);
|
||||
if(lv_streq("selected", name)) lv_dropdown_set_selected(item, lv_xml_atoi(value), LV_ANIM_OFF);
|
||||
if(lv_streq("symbol", name)) lv_dropdown_set_symbol(item, lv_xml_get_image(value));
|
||||
if(lv_streq("symbol", name)) lv_dropdown_set_symbol(item, lv_xml_get_image(&state->ctx, value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ void * lv_xml_event_call_function_create(lv_xml_parser_state_t * state, const ch
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_event_cb_t cb = lv_xml_get_event_cb(cb_txt);
|
||||
lv_event_cb_t cb = lv_xml_get_event_cb(&state->ctx, cb_txt);
|
||||
if(cb == NULL) {
|
||||
LV_LOG_WARN("Couldn't add call function event because \"%s\" callback is not found.", cb_txt);
|
||||
return NULL;
|
||||
|
||||
@@ -60,7 +60,7 @@ void lv_xml_image_apply(lv_xml_parser_state_t * state, const char ** attrs)
|
||||
const char * name = attrs[i];
|
||||
const char * value = attrs[i + 1];
|
||||
|
||||
if(lv_streq("src", name)) lv_image_set_src(item, lv_xml_get_image(value));
|
||||
if(lv_streq("src", name)) lv_image_set_src(item, lv_xml_get_image(&state->ctx, value));
|
||||
if(lv_streq("inner_align", name)) lv_image_set_inner_align(item, image_align_to_enum(value));
|
||||
if(lv_streq("rotation", name)) lv_image_set_rotation(item, lv_xml_atoi(value));
|
||||
if(lv_streq("scale_x", name)) lv_image_set_scale_x(item, lv_xml_atoi(value));
|
||||
|
||||
@@ -57,6 +57,7 @@ void lv_xml_label_apply(lv_xml_parser_state_t * state, const char ** attrs)
|
||||
|
||||
if(lv_streq("text", name)) lv_label_set_text(item, value);
|
||||
if(lv_streq("long_mode", name)) lv_label_set_long_mode(item, long_mode_text_to_enum_value(value));
|
||||
if(lv_streq("bind_text", name)) lv_label_bind_text(item, lv_xml_get_subject(&state->ctx, value), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +69,9 @@ static lv_label_long_mode_t long_mode_text_to_enum_value(const char * txt)
|
||||
{
|
||||
if(lv_streq("wrap", txt)) return LV_LABEL_LONG_MODE_WRAP;
|
||||
if(lv_streq("scroll", txt)) return LV_LABEL_LONG_MODE_SCROLL;
|
||||
if(lv_streq("scroll_circular", txt)) return LV_LABEL_LONG_MODE_SCROLL_CIRCULAR;
|
||||
if(lv_streq("dots", txt)) return LV_LABEL_LONG_MODE_DOTS;
|
||||
if(lv_streq("clip", txt)) return LV_LABEL_LONG_MODE_CLIP;
|
||||
|
||||
LV_LOG_WARN("%s is an unknown value for label's long_mode", txt);
|
||||
return 0; /*Return 0 in lack of a better option. */
|
||||
|
||||
@@ -163,7 +163,7 @@ static void apply_styles(lv_xml_parser_state_t * state, lv_obj_t * obj, const ch
|
||||
else SET_STYLE_IF(bg_grad_stop, lv_xml_atoi(value));
|
||||
else SET_STYLE_IF(bg_grad, lv_xml_component_get_grad(&state->ctx, value));
|
||||
|
||||
else SET_STYLE_IF(bg_image_src, lv_xml_get_image(value));
|
||||
else SET_STYLE_IF(bg_image_src, lv_xml_get_image(&state->ctx, value));
|
||||
else SET_STYLE_IF(bg_image_tiled, lv_xml_to_bool(value));
|
||||
else SET_STYLE_IF(bg_image_recolor, lv_xml_to_color(value));
|
||||
else SET_STYLE_IF(bg_image_recolor_opa, lv_xml_to_opa(value));
|
||||
@@ -187,7 +187,7 @@ static void apply_styles(lv_xml_parser_state_t * state, lv_obj_t * obj, const ch
|
||||
else SET_STYLE_IF(shadow_opa, lv_xml_to_opa(value));
|
||||
|
||||
else SET_STYLE_IF(text_color, lv_xml_to_color(value));
|
||||
else SET_STYLE_IF(text_font, lv_xml_get_font(value));
|
||||
else SET_STYLE_IF(text_font, lv_xml_get_font(&state->ctx, value));
|
||||
else SET_STYLE_IF(text_opa, lv_xml_to_opa(value));
|
||||
else SET_STYLE_IF(text_align, lv_xml_text_align_to_enum(value));
|
||||
else SET_STYLE_IF(text_letter_space, lv_xml_atoi(value));
|
||||
@@ -209,7 +209,7 @@ static void apply_styles(lv_xml_parser_state_t * state, lv_obj_t * obj, const ch
|
||||
else SET_STYLE_IF(arc_opa, lv_xml_to_opa(value));
|
||||
else SET_STYLE_IF(arc_width, lv_xml_atoi(value));
|
||||
else SET_STYLE_IF(arc_rounded, lv_xml_to_bool(value));
|
||||
else SET_STYLE_IF(arc_image_src, lv_xml_get_image(value));
|
||||
else SET_STYLE_IF(arc_image_src, lv_xml_get_image(&state->ctx, value));
|
||||
|
||||
else SET_STYLE_IF(opa, lv_xml_to_opa(value));
|
||||
else SET_STYLE_IF(opa_layered, lv_xml_to_opa(value));
|
||||
@@ -227,7 +227,7 @@ static void apply_styles(lv_xml_parser_state_t * state, lv_obj_t * obj, const ch
|
||||
else SET_STYLE_IF(transform_pivot_x, lv_xml_atoi(value));
|
||||
else SET_STYLE_IF(transform_pivot_y, lv_xml_atoi(value));
|
||||
else SET_STYLE_IF(transform_skew_x, lv_xml_atoi(value));
|
||||
else SET_STYLE_IF(bitmap_mask_src, lv_xml_get_image(value));
|
||||
else SET_STYLE_IF(bitmap_mask_src, lv_xml_get_image(&state->ctx, value));
|
||||
else SET_STYLE_IF(rotary_sensitivity, lv_xml_atoi(value));
|
||||
|
||||
else SET_STYLE_IF(layout, lv_xml_layout_to_enum(value));
|
||||
|
||||
@@ -63,6 +63,7 @@ void lv_xml_slider_apply(lv_xml_parser_state_t * state, const char ** attrs)
|
||||
bool v2 = lv_xml_to_bool(buf_p);
|
||||
lv_bar_set_value(item, v1, v2);
|
||||
}
|
||||
if(lv_streq("bind_value", name)) lv_slider_bind_value(item, lv_xml_get_subject(&state->ctx, value));
|
||||
if(lv_streq("start_value", name)) {
|
||||
char buf[64];
|
||||
lv_strlcpy(buf, value, sizeof(buf));
|
||||
@@ -71,7 +72,6 @@ void lv_xml_slider_apply(lv_xml_parser_state_t * state, const char ** attrs)
|
||||
bool v2 = lv_xml_to_bool(buf_p);
|
||||
lv_bar_set_start_value(item, v1, v2);
|
||||
}
|
||||
|
||||
if(lv_streq("orientation", name)) lv_slider_set_orientation(item, orentation_text_to_enum_value(value));
|
||||
if(lv_streq("mode", name)) lv_slider_set_mode(item, mode_text_to_enum_value(value));
|
||||
if(lv_streq("range_min", name)) lv_slider_set_range(item, lv_xml_atoi(value), lv_slider_get_max_value(item));
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
@@ -0,0 +1,15 @@
|
||||
<globals>
|
||||
<config name="mylib" help="This is my great component library"/>
|
||||
|
||||
<consts>
|
||||
<int name="global_int" value="30"/>
|
||||
</consts>
|
||||
|
||||
<styles>
|
||||
<style name="global_red" bg_color="0xf00" radius="global_small_unit" pad_all="12px"/>
|
||||
</styles>
|
||||
|
||||
<subjects>
|
||||
<int name="global_subject" value="22"/>
|
||||
</subjects>
|
||||
</globals>
|
||||
@@ -0,0 +1,23 @@
|
||||
<component>
|
||||
<consts>
|
||||
<int name="local_int" value="15"/>
|
||||
<color name="local_blue" value="0x0000ff"/>
|
||||
</consts>
|
||||
|
||||
<styles>
|
||||
<style name="local_style" bg_color="#local_blue" border_color="#global_red" border_width="5"/>
|
||||
</styles>
|
||||
|
||||
<subjects>
|
||||
<int name="local_subject" value="10"/>
|
||||
</subjects>
|
||||
|
||||
|
||||
<view extends="lv_obj" width="480" height="300" flex_flow="column">
|
||||
<lv_label bind_text="global_subject"/>
|
||||
<lv_slider bind_value="global_subject" range_max="#global_int"/>
|
||||
|
||||
<lv_label bind_text="local_subject" style_margin_top="32px"/>
|
||||
<lv_slider bind_value="local_subject" range_max="#local_int"/>
|
||||
</view>
|
||||
</component>
|
||||
@@ -27,7 +27,7 @@ static void count_event_cb(lv_event_t * e)
|
||||
void test_xml_event_call_function_attr(void)
|
||||
{
|
||||
|
||||
lv_xml_register_event_cb("count_cb", count_event_cb);
|
||||
lv_xml_register_event_cb(NULL, "count_cb", count_event_cb);
|
||||
|
||||
lv_obj_t * scr = lv_screen_active();
|
||||
|
||||
@@ -80,7 +80,7 @@ void test_xml_event_call_function_component(void)
|
||||
"</component>"
|
||||
};
|
||||
|
||||
lv_xml_register_event_cb("count_cb", count_event_cb);
|
||||
lv_xml_register_event_cb(NULL, "count_cb", count_event_cb);
|
||||
lv_xml_component_register_from_data("my_button", xml);
|
||||
lv_xml_create(lv_screen_active(), "my_button", NULL);
|
||||
|
||||
|
||||
@@ -272,11 +272,11 @@ void test_xml_image_and_font(void)
|
||||
/*Monstserrat fonts are registered by LVGL */
|
||||
LV_IMAGE_DECLARE(img_render_lvgl_logo_l8);
|
||||
LV_IMAGE_DECLARE(img_render_lvgl_logo_rgb565);
|
||||
lv_xml_register_image("test_img1", &img_render_lvgl_logo_l8);
|
||||
lv_xml_register_image("test_img2", &img_render_lvgl_logo_rgb565);
|
||||
lv_xml_register_image(NULL, "test_img1", &img_render_lvgl_logo_l8);
|
||||
lv_xml_register_image(NULL, "test_img2", &img_render_lvgl_logo_rgb565);
|
||||
|
||||
lv_xml_register_font("lv_montserrat_16", &lv_font_montserrat_16);
|
||||
lv_xml_register_font("lv_montserrat_18", &lv_font_montserrat_18);
|
||||
lv_xml_register_font(NULL, "lv_montserrat_16", &lv_font_montserrat_16);
|
||||
lv_xml_register_font(NULL, "lv_montserrat_18", &lv_font_montserrat_18);
|
||||
|
||||
lv_xml_component_register_from_data("btn", btn_xml);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ void tearDown(void)
|
||||
void test_xml_image_with_attrs(void)
|
||||
{
|
||||
LV_IMAGE_DECLARE(test_img_lvgl_logo_png);
|
||||
lv_xml_register_image("logo", &test_img_lvgl_logo_png);
|
||||
lv_xml_register_image(NULL, "logo", &test_img_lvgl_logo_png);
|
||||
lv_obj_t * scr = lv_screen_active();
|
||||
|
||||
const char * image1_attrs[] = {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#if LV_BUILD_TEST
|
||||
#include "../lvgl.h"
|
||||
|
||||
#include "unity/unity.h"
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
/* Function run before every test */
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
/* Function run after every test */
|
||||
lv_obj_clean(lv_screen_active());
|
||||
}
|
||||
|
||||
void test_xml_label_with_attrs(void)
|
||||
{
|
||||
lv_obj_t * scr = lv_screen_active();
|
||||
|
||||
const char * textarea1_attrs[] = {
|
||||
"text", "This is the text with ellipses added automatically",
|
||||
"long_mode", "dots",
|
||||
"width", "100",
|
||||
"height", "40",
|
||||
"align", "center",
|
||||
"style_bg_opa", "50%",
|
||||
"style_bg_color", "0xf00",
|
||||
NULL, NULL,
|
||||
};
|
||||
|
||||
lv_xml_create(scr, "lv_label", textarea1_attrs);
|
||||
|
||||
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT("xml/lv_label.png");
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
#if LV_BUILD_TEST || 1
|
||||
#if LV_BUILD_TEST
|
||||
#include "../lvgl.h"
|
||||
|
||||
#include "unity/unity.h"
|
||||
@@ -16,7 +16,7 @@ void tearDown(void)
|
||||
|
||||
void test_xml_view2_from_xml(void)
|
||||
{
|
||||
lv_xml_register_font("lv_montserrat_30", &lv_font_montserrat_30);
|
||||
lv_xml_register_font(NULL, "lv_montserrat_30", &lv_font_montserrat_30);
|
||||
lv_xml_component_register_from_file("A:src/test_assets/xml/view2.xml");
|
||||
|
||||
lv_xml_create(lv_screen_active(), "view2", NULL);
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#if LV_BUILD_TEST
|
||||
#include "../lvgl.h"
|
||||
|
||||
#include "unity/unity.h"
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
/* Function run before every test */
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
/* Function run after every test */
|
||||
lv_obj_clean(lv_screen_active());
|
||||
}
|
||||
|
||||
void test_xml_view3_scoping(void)
|
||||
{
|
||||
lv_xml_component_register_from_file("A:src/test_assets/xml/globals.xml");
|
||||
lv_xml_component_register_from_file("A:src/test_assets/xml/view3.xml");
|
||||
|
||||
lv_xml_create(lv_screen_active(), "view3", NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT("xml/view3.png");
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user