feat(xml): add gradient support

This commit is contained in:
Gabor Kiss-Vamosi
2025-01-18 07:50:18 +01:00
parent ecfe33480b
commit b78a9b447a
13 changed files with 382 additions and 11 deletions
+10 -2
View File
@@ -1,4 +1,12 @@
<component> <component>
<gradients>
<horizontal_gradient name="grad1" >
<stop color="#ff0000" frac="30%" opa="100%"/>
<stop color="#00ff00" frac="200" opa="100%"/>
</horizontal_gradient>
</gradients>
<consts> <consts>
<px name="size" value="100%"/> <px name="size" value="100%"/>
</consts> </consts>
@@ -12,11 +20,11 @@
</api> </api>
<styles> <styles>
<style name="gray" bg_color="0x888888"/> <style name="gray" bg_grad="grad1"/>
<style name="blue" bg_color="0x0000ff"/> <style name="blue" bg_color="0x0000ff"/>
</styles> </styles>
<view extends="lv_obj" style_radius="3" width="#size" height="content" style_bg_color="$bg_color" > <view extends="lv_obj" style_radius="3" width="#size" height="content" styles="gray" style_bg_color="$bg_color" >
<lv_label text="$title" align="left_mid"/> <lv_label text="$title" align="left_mid"/>
<my_button styles="$btn_rel_style $btn_pr_style:pressed" btn_text="$action" align="right_mid"/> <my_button styles="$btn_rel_style $btn_pr_style:pressed" btn_text="$action" align="right_mid"/>
</view> </view>
-1
View File
@@ -10,7 +10,6 @@
</styles> </styles>
<view extends="lv_obj" width="280" height="content" style_bg_color="#light_blue"> <view extends="lv_obj" width="280" height="content" style_bg_color="#light_blue">
<lv_label text="Hello"/>
<my_card title="Card 1" <my_card title="Card 1"
y="0" y="0"
btn_rel_style="btn_style" btn_rel_style="btn_style"
+2
View File
@@ -194,6 +194,8 @@ lv_blend_mode_t lv_xml_blend_mode_to_enum(const char * txt)
LV_LOG_WARN("%s is an unknown value for blend_mode", txt); LV_LOG_WARN("%s is an unknown value for blend_mode", txt);
return 0; /*Return 0 in lack of a better option. */ return 0; /*Return 0 in lack of a better option. */
} }
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
+197 -5
View File
@@ -191,14 +191,43 @@ lv_result_t lv_xml_component_unregister(const char * name)
lv_free((char *)ctx->name); lv_free((char *)ctx->name);
lv_free((char *)ctx->view_def); lv_free((char *)ctx->view_def);
lv_xml_const_t * cnst;
LV_LL_READ(&ctx->const_ll, cnst) {
lv_free((char *)cnst->name);
lv_free((char *)cnst->value);
}
lv_ll_clear(&ctx->const_ll);
lv_xml_param_t * param;
LV_LL_READ(&ctx->param_ll, param) {
lv_free((char *)param->name);
lv_free((char *)param->def);
lv_free((char *)param->type);
}
lv_ll_clear(&ctx->param_ll); lv_ll_clear(&ctx->param_ll);
lv_xml_style_t * style;
LV_LL_READ(&ctx->style_ll, style) {
lv_free((char *)style->name);
lv_free((char *)style->long_name);
lv_style_reset(&style->style);
}
lv_ll_clear(&ctx->style_ll); lv_ll_clear(&ctx->style_ll);
lv_xml_grad_t * grad;
LV_LL_READ(&ctx->gradient_ll, grad) {
lv_free((char *)grad->name);
}
lv_ll_clear(&ctx->gradient_ll);
lv_free(ctx); lv_free(ctx);
return LV_RESULT_OK; return LV_RESULT_OK;
} }
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
@@ -222,6 +251,161 @@ static void process_const_element(lv_xml_parser_state_t * state, const char ** a
cnst->value = lv_strdup(value); cnst->value = lv_strdup(value);
} }
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;
lv_memzero(dsc, sizeof(lv_grad_dsc_t));
dsc->extend = LV_GRAD_EXTEND_PAD;
if(lv_streq(tag_name, "linear_gradient")) {
dsc->dir = LV_GRAD_DIR_LINEAR;
char buf[64];
char * buf_p = buf;
const char * start = lv_xml_get_value_of(attrs, "start");
lv_strlcpy(buf, start, sizeof(buf));
dsc->params.linear.start.x = lv_xml_to_size(lv_xml_split_str(&buf_p, ' '));
dsc->params.linear.start.y = lv_xml_to_size(buf_p);
buf_p = buf;
const char * end = lv_xml_get_value_of(attrs, "end");
lv_strlcpy(buf, end, sizeof(buf));
dsc->params.linear.end.x = lv_xml_to_size(lv_xml_split_str(&buf_p, ' '));
dsc->params.linear.end.y = lv_xml_to_size(buf_p);
}
else if(lv_streq(tag_name, "radial_gradient")) {
dsc->dir = LV_GRAD_DIR_RADIAL;
char buf[64];
char * buf_p = buf;
const char * center = lv_xml_get_value_of(attrs, "center");
if(center) {
lv_strlcpy(buf, center, sizeof(buf));
dsc->params.radial.end.x = lv_xml_to_size(lv_xml_split_str(&buf_p, ' '));
dsc->params.radial.end.y = lv_xml_to_size(buf_p);
}
else {
dsc->params.radial.end.x = lv_pct(50);
dsc->params.radial.end.y = lv_pct(50);
}
buf_p = buf;
const char * center_edge = lv_xml_get_value_of(attrs, "edge");
if(center_edge) {
lv_strlcpy(buf, center_edge, sizeof(buf));
dsc->params.radial.end_extent.x = lv_xml_to_size(lv_xml_split_str(&buf_p, ' '));
dsc->params.radial.end_extent.y = lv_xml_to_size(buf_p);
}
else {
dsc->params.radial.end_extent.x = lv_pct(100);
dsc->params.radial.end_extent.y = lv_pct(100);
}
buf_p = buf;
const char * center_radius = lv_xml_get_value_of(attrs, "radius");
if(center_radius) {
int32_t r = lv_xml_atoi(center_radius);
lv_strlcpy(buf, center_edge, sizeof(buf));
dsc->params.radial.end_extent.x = dsc->params.radial.end.x + r;
dsc->params.radial.end_extent.y = dsc->params.radial.end.y;
}
buf_p = buf;
const char * focal = lv_xml_get_value_of(attrs, "focal_center");
if(focal) {
lv_strlcpy(buf, focal, sizeof(buf));
dsc->params.radial.focal.x = lv_xml_to_size(lv_xml_split_str(&buf_p, ' '));
dsc->params.radial.focal.y = lv_xml_to_size(buf_p);
}
else {
dsc->params.radial.focal.x = dsc->params.radial.end.x;
dsc->params.radial.focal.y = dsc->params.radial.end.y;
}
buf_p = buf;
const char * focal_edge = lv_xml_get_value_of(attrs, "focal_edge");
if(focal_edge) {
lv_strlcpy(buf, focal_edge, sizeof(buf));
dsc->params.radial.focal_extent.x = lv_xml_to_size(lv_xml_split_str(&buf_p, ' '));
dsc->params.radial.focal_extent.y = lv_xml_to_size(buf_p);
}
else {
dsc->params.radial.focal_extent.x = dsc->params.radial.focal.x;
dsc->params.radial.focal_extent.y = dsc->params.radial.focal.y;
}
buf_p = buf;
const char * focal_radius = lv_xml_get_value_of(attrs, "focal_radius");
if(focal_radius) {
int32_t r = lv_xml_atoi(center_radius);
lv_strlcpy(buf, center_edge, sizeof(buf));
dsc->params.radial.focal_extent.x = dsc->params.radial.focal.x + r;
dsc->params.radial.focal_extent.y = dsc->params.radial.focal.y;
}
}
else if(lv_streq(tag_name, "conical_gradient")) {
dsc->dir = LV_GRAD_DIR_CONICAL;
char buf[64];
char * buf_p = buf;
const char * center = lv_xml_get_value_of(attrs, "center");
if(center) {
lv_strlcpy(buf, center, sizeof(buf));
dsc->params.conical.center.x = lv_xml_to_size(lv_xml_split_str(&buf_p, ' '));
dsc->params.conical.center.y = lv_xml_to_size(buf_p);
}
else {
dsc->params.conical.center.x = lv_pct(50);
dsc->params.conical.center.y = lv_pct(50);
}
buf_p = buf;
const char * angle = lv_xml_get_value_of(attrs, "angle");
if(angle) {
lv_strlcpy(buf, angle, sizeof(buf));
dsc->params.conical.start_angle = lv_xml_atoi(lv_xml_split_str(&buf_p, ' '));
dsc->params.conical.end_angle = lv_xml_atoi(buf_p);
}
else {
dsc->params.conical.start_angle = 0;
dsc->params.conical.end_angle = 360;
}
}
else if(lv_streq(tag_name, "horizontal_gradient")) {
dsc->dir = LV_GRAD_DIR_HOR;
}
else if(lv_streq(tag_name, "vertical_gradient")) {
dsc->dir = LV_GRAD_DIR_VER;
}
else {
LV_LOG_WARN("Unknown gradient type: %s", tag_name);
}
}
static void process_grad_stop_element(lv_xml_parser_state_t * state, const char ** attrs)
{
/*Add the stop to the last gradient*/
lv_xml_grad_t * grad = lv_ll_get_tail(&state->ctx.gradient_ll);
lv_grad_dsc_t * dsc = &grad->grad_dsc;
uint32_t idx = dsc->stops_count;
if(idx == LV_GRADIENT_MAX_STOPS) {
LV_LOG_WARN("Too many gradient stops. Incresase LV_GRADIENT_MAX_STOPS");
return;
}
const char * color_value = lv_xml_get_value_of(attrs, "color");
const char * opa_value = lv_xml_get_value_of(attrs, "opa");
const char * offset_value = lv_xml_get_value_of(attrs, "offset");
dsc->stops[idx].color = color_value ? lv_xml_to_color(color_value) : lv_color_black();
dsc->stops[idx].opa = opa_value ? lv_xml_to_opa(opa_value) : LV_OPA_COVER;
dsc->stops[idx].frac = offset_value ? lv_xml_to_opa(offset_value) : (uint8_t)((int32_t)idx * 255 /
(LV_GRADIENT_MAX_STOPS - 1));
dsc->stops_count++;
}
static void process_prop_element(lv_xml_parser_state_t * state, const char ** attrs) static void process_prop_element(lv_xml_parser_state_t * state, const char ** attrs)
{ {
lv_xml_param_t * prop = lv_ll_ins_tail(&state->ctx.param_ll); lv_xml_param_t * prop = lv_ll_ins_tail(&state->ctx.param_ll);
@@ -235,6 +419,7 @@ static void process_prop_element(lv_xml_parser_state_t * state, const char ** at
prop->type = lv_strdup(type); prop->type = lv_strdup(type);
} }
static void start_metadata_handler(void * user_data, const char * name, const char ** attrs) static void start_metadata_handler(void * user_data, const char * name, const char ** attrs)
{ {
lv_xml_parser_state_t * state = (lv_xml_parser_state_t *)user_data; lv_xml_parser_state_t * state = (lv_xml_parser_state_t *)user_data;
@@ -260,22 +445,29 @@ static void start_metadata_handler(void * user_data, const char * name, const ch
if(lv_streq(name, "widget")) state->ctx.is_widget = 1; if(lv_streq(name, "widget")) state->ctx.is_widget = 1;
if(old_section != state->section) return; /*Ignore the section opening, e.g. <styles>*/
/* Process elements based on current context */ /* Process elements based on current context */
switch(state->section) { switch(state->section) {
case LV_XML_PARSER_SECTION_API: case LV_XML_PARSER_SECTION_API:
if(old_section != state->section) return; /*Ignore the section opening, e.g. <api>*/
process_prop_element(state, attrs); process_prop_element(state, attrs);
break; break;
case LV_XML_PARSER_SECTION_CONSTS: case LV_XML_PARSER_SECTION_CONSTS:
if(old_section != state->section) return; /*Ignore the section opening, e.g. <consts>*/
process_const_element(state, attrs); process_const_element(state, attrs);
break; break;
case LV_XML_PARSER_SECTION_GRAD:
if(old_section != state->section) return; /*Ignore the section opening, e.g. <gradients>*/
process_grad_element(state, name, attrs);
break;
case LV_XML_PARSER_SECTION_GRAD_STOP:
process_grad_stop_element(state, attrs);
break;
case LV_XML_PARSER_SECTION_STYLES: case LV_XML_PARSER_SECTION_STYLES:
if(lv_streq(name, "style")) { if(old_section != state->section) return; /*Ignore the section opening, e.g. <styles>*/
lv_xml_style_register(&state->ctx, attrs); lv_xml_style_register(&state->ctx, attrs);
}
break; break;
default: default:
@@ -30,6 +30,7 @@ struct _lv_xml_component_ctx_t {
lv_ll_t style_ll; lv_ll_t style_ll;
lv_ll_t const_ll; lv_ll_t const_ll;
lv_ll_t param_ll; lv_ll_t param_ll;
lv_ll_t gradient_ll;
const char * view_def; const char * view_def;
struct _lv_widget_processor_t * root_widget; struct _lv_widget_processor_t * root_widget;
uint32_t is_widget : 1; /*1: not component but widget registered as a component for preview*/ uint32_t is_widget : 1; /*1: not component but widget registered as a component for preview*/
+16
View File
@@ -45,6 +45,7 @@ void lv_xml_parser_state_init(lv_xml_parser_state_t * state)
lv_ll_init(&state->ctx.style_ll, sizeof(lv_xml_style_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.const_ll, sizeof(lv_xml_const_t));
lv_ll_init(&state->ctx.param_ll, sizeof(lv_xml_param_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_ll_init(&state->parent_ll, sizeof(lv_obj_t *));
} }
@@ -55,6 +56,14 @@ void lv_xml_parser_start_section(lv_xml_parser_state_t * state, const char * nam
state->section = LV_XML_PARSER_SECTION_API; state->section = LV_XML_PARSER_SECTION_API;
return; return;
} }
if(lv_streq(name, "gradients")) {
state->section = LV_XML_PARSER_SECTION_GRAD;
return;
}
if(state->section == LV_XML_PARSER_SECTION_GRAD && lv_streq(name, "stop")) {
state->section = LV_XML_PARSER_SECTION_GRAD_STOP;
return;
}
else if(lv_streq(name, "consts")) { else if(lv_streq(name, "consts")) {
state->section = LV_XML_PARSER_SECTION_CONSTS; state->section = LV_XML_PARSER_SECTION_CONSTS;
return; return;
@@ -75,10 +84,17 @@ void lv_xml_parser_end_section(lv_xml_parser_state_t * state, const char * name)
/* Reset context when leaving a block */ /* Reset context when leaving a block */
if(lv_streq(name, "params") || if(lv_streq(name, "params") ||
lv_streq(name, "consts") || lv_streq(name, "consts") ||
lv_streq(name, "gradients") ||
lv_streq(name, "styles") || lv_streq(name, "styles") ||
lv_streq(name, "view")) { lv_streq(name, "view")) {
state->section = LV_XML_PARSER_SECTION_NONE; state->section = LV_XML_PARSER_SECTION_NONE;
} }
/*When processing gradient stops, but not a stop was closed got bacg to gradient processing
* E.g. </linear_gradient>*/
if(state->section == LV_XML_PARSER_SECTION_GRAD_STOP && !lv_streq(name, "stop")) {
state->section = LV_XML_PARSER_SECTION_GRAD;
}
} }
void * lv_xml_state_get_parent(lv_xml_parser_state_t * state) void * lv_xml_state_get_parent(lv_xml_parser_state_t * state)
+8
View File
@@ -14,6 +14,7 @@ extern "C" {
* INCLUDES * INCLUDES
*********************/ *********************/
#include "../../misc/lv_types.h" #include "../../misc/lv_types.h"
#include "../../misc/lv_style.h"
#if LV_USE_XML #if LV_USE_XML
#include "lv_xml_component.h" #include "lv_xml_component.h"
@@ -31,6 +32,8 @@ typedef enum {
LV_XML_PARSER_SECTION_NONE, LV_XML_PARSER_SECTION_NONE,
LV_XML_PARSER_SECTION_API, LV_XML_PARSER_SECTION_API,
LV_XML_PARSER_SECTION_CONSTS, LV_XML_PARSER_SECTION_CONSTS,
LV_XML_PARSER_SECTION_GRAD,
LV_XML_PARSER_SECTION_GRAD_STOP,
LV_XML_PARSER_SECTION_STYLES, LV_XML_PARSER_SECTION_STYLES,
LV_XML_PARSER_SECTION_VIEW LV_XML_PARSER_SECTION_VIEW
} lv_xml_parser_section_t; } lv_xml_parser_section_t;
@@ -57,6 +60,11 @@ typedef struct {
const char * type; const char * type;
} lv_xml_param_t; } lv_xml_param_t;
typedef struct {
const char * name;
lv_grad_dsc_t grad_dsc;
} lv_xml_grad_t;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
+14
View File
@@ -144,6 +144,7 @@ void lv_xml_style_register(lv_xml_component_ctx_t * ctx, const char ** attrs)
else SET_STYLE_IF(bg_grad_color, lv_xml_to_color(value)); else SET_STYLE_IF(bg_grad_color, lv_xml_to_color(value));
else SET_STYLE_IF(bg_main_stop, lv_xml_atoi(value)); else SET_STYLE_IF(bg_main_stop, lv_xml_atoi(value));
else SET_STYLE_IF(bg_grad_stop, lv_xml_atoi(value)); 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(value));
else SET_STYLE_IF(bg_image_tiled, lv_xml_to_bool(value)); else SET_STYLE_IF(bg_image_tiled, lv_xml_to_bool(value));
@@ -228,6 +229,8 @@ void lv_xml_style_register(lv_xml_component_ctx_t * ctx, const char ** attrs)
else SET_STYLE_IF(grid_cell_row_pos, lv_xml_atoi(value)); else SET_STYLE_IF(grid_cell_row_pos, lv_xml_atoi(value));
else SET_STYLE_IF(grid_cell_row_span, lv_xml_atoi(value)); else SET_STYLE_IF(grid_cell_row_span, lv_xml_atoi(value));
else SET_STYLE_IF(grid_cell_y_align, lv_xml_grid_align_to_enum(value)); else SET_STYLE_IF(grid_cell_y_align, lv_xml_grid_align_to_enum(value));
else { else {
LV_LOG_WARN("%s style property is not supported", name); LV_LOG_WARN("%s style property is not supported", name);
} }
@@ -315,6 +318,17 @@ lv_xml_style_t * lv_xml_get_style_by_name(lv_xml_component_ctx_t * ctx, const ch
return NULL; return NULL;
} }
lv_grad_dsc_t * lv_xml_component_get_grad(lv_xml_component_ctx_t * ctx, const char * name)
{
lv_xml_grad_t * d;
LV_LL_READ(&ctx->gradient_ll, d) {
if(lv_streq(d->name, name)) return &d->grad_dsc;
}
return NULL;
}
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
+8
View File
@@ -78,6 +78,14 @@ const char * lv_xml_style_string_process(char * txt, lv_style_selector_t * selec
*/ */
lv_xml_style_t * lv_xml_get_style_by_name(lv_xml_component_ctx_t * ctx, const char * name); lv_xml_style_t * lv_xml_get_style_by_name(lv_xml_component_ctx_t * ctx, const char * name);
/**
* Get a gradient descriptor defined for a component
* @param ctx component context where the gradient should be found
* @param name name of the gradient
* @return a gradient descriptor
*/
lv_grad_dsc_t * lv_xml_component_get_grad(lv_xml_component_ctx_t * ctx, const char * name);
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/
+4 -3
View File
@@ -23,7 +23,7 @@
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static void apply_styles(lv_obj_t * obj, const char * name, const char * value); static void apply_styles(lv_xml_parser_state_t * state, lv_obj_t * obj, const char * name, const char * value);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
@@ -108,7 +108,7 @@ void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs)
else if(lv_streq("styles", name)) lv_xml_style_add_to_obj(state, item, value); else if(lv_streq("styles", name)) lv_xml_style_add_to_obj(state, item, value);
else if(lv_strlen(name) > 6 && lv_memcmp("style_", name, 6) == 0) { else if(lv_strlen(name) > 6 && lv_memcmp("style_", name, 6) == 0) {
apply_styles(item, name, value); apply_styles(state, item, name, value);
} }
} }
} }
@@ -117,7 +117,7 @@ void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs)
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
static void apply_styles(lv_obj_t * obj, const char * name, const char * value) static void apply_styles(lv_xml_parser_state_t * state, lv_obj_t * obj, const char * name, const char * value)
{ {
char name_local[512]; char name_local[512];
lv_strlcpy(name_local, name, sizeof(name_local)); lv_strlcpy(name_local, name, sizeof(name_local));
@@ -159,6 +159,7 @@ static void apply_styles(lv_obj_t * obj, const char * name, const char * value)
else SET_STYLE_IF(bg_grad_color, lv_xml_to_color(value)); else SET_STYLE_IF(bg_grad_color, lv_xml_to_color(value));
else SET_STYLE_IF(bg_main_stop, lv_xml_atoi(value)); else SET_STYLE_IF(bg_main_stop, lv_xml_atoi(value));
else SET_STYLE_IF(bg_grad_stop, lv_xml_atoi(value)); 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(value));
else SET_STYLE_IF(bg_image_tiled, lv_xml_to_bool(value)); else SET_STYLE_IF(bg_image_tiled, lv_xml_to_bool(value));
Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

+122
View File
@@ -0,0 +1,122 @@
#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_style_gradients(void)
{
lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_ROW_WRAP);
lv_obj_set_style_pad_all(lv_screen_active(), 16, 0);
const char * lin_grad_xml =
"<component>"
" <gradients>"
" <linear_gradient name=\"grad1\" start=\"50 50\" end=\"100 80\">"
" <stop color=\"#ff0000\" offset=\"20%\" opa=\"100%\"/>"
" <stop color=\"#00ff00\" offset=\"240\" opa=\"100%\"/>"
" </linear_gradient>"
" </gradients>"
""
" <view extends=\"lv_obj\" width=\"200\" height=\"150\" style_bg_grad=\"grad1\">"
" </view>"
"</component>";
lv_xml_component_register_from_data("lin_grad", lin_grad_xml);
lv_xml_create(lv_screen_active(), "lin_grad", NULL);
const char * rad_grad_def_xml =
"<component>"
" <gradients>"
" <radial_gradient name=\"grad1\">"
" <stop color=\"#ff0000\" opa=\"100%\"/>"
" <stop color=\"#00ff00\" opa=\"100%\"/>"
" </radial_gradient>"
" </gradients>"
""
" <view extends=\"lv_obj\" width=\"200\" height=\"150\" style_bg_grad=\"grad1\">"
" </view>"
"</component>";
lv_xml_component_register_from_data("rad_grad_def", rad_grad_def_xml);
lv_xml_create(lv_screen_active(), "rad_grad_def", NULL);
const char * rad_grad_ofs_xml =
"<component>"
" <gradients>"
" <radial_gradient name=\"grad1\" center=\"100 50%\" edge=\"200 50\" "
" focal_center=\"50 80%\" focal_edge=\"55 80%\">"
" <stop color=\"#ff0000\" opa=\"100%\"/>"
" <stop color=\"#00ff00\" opa=\"100%\"/>"
" </radial_gradient>"
" </gradients>"
""
" <view extends=\"lv_obj\" width=\"200\" height=\"150\" style_bg_grad=\"grad1\">"
" </view>"
"</component>";
lv_xml_component_register_from_data("rad_grad_ofs", rad_grad_ofs_xml);
lv_xml_create(lv_screen_active(), "rad_grad_ofs", NULL);
const char * con_grad_def_xml =
"<component>"
" <gradients>"
" <conical_gradient name=\"grad1\">"
" <stop color=\"#ff0000\" opa=\"100%\"/>"
" <stop color=\"#00ff00\" opa=\"100%\"/>"
" </conical_gradient>"
" </gradients>"
""
" <view extends=\"lv_obj\" width=\"200\" height=\"150\" style_bg_grad=\"grad1\">"
" </view>"
"</component>";
lv_xml_component_register_from_data("con_grad_def", con_grad_def_xml);
lv_xml_create(lv_screen_active(), "con_grad_def", NULL);
const char * con_grad_xml =
"<component>"
" <gradients>"
" <conical_gradient name=\"grad1\" center=\"80 50%\" angle=\"45 270\">"
" <stop color=\"#ff0000\" opa=\"100%\"/>"
" <stop color=\"#00ff00\" opa=\"100%\"/>"
" </conical_gradient>"
" </gradients>"
""
" <view extends=\"lv_obj\" width=\"200\" height=\"150\" style_bg_grad=\"grad1\">"
" </view>"
"</component>";
lv_xml_component_register_from_data("con_grad", con_grad_xml);
lv_xml_create(lv_screen_active(), "con_grad", NULL);
const char * hor_grad_xml =
"<component>"
" <gradients>"
" <horizontal_gradient name=\"grad1\">"
" <stop color=\"#ff0000\" offset=\"20%\" opa=\"40%\"/>"
" <stop color=\"#00ff00\" offset=\"128\" opa=\"100%\"/>"
" </horizontal_gradient>"
" </gradients>"
""
" <view extends=\"lv_obj\" width=\"200\" height=\"150\" style_bg_grad=\"grad1\">"
" </view>"
"</component>";
lv_xml_component_register_from_data("hor_grad", hor_grad_xml);
lv_xml_create(lv_screen_active(), "hor_grad", NULL);
TEST_ASSERT_EQUAL_SCREENSHOT("xml/gradients.png");
}
#endif