mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-30 23:51:54 +08:00
feat(xml): add gradient support
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
@@ -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*/
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
@@ -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
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
@@ -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
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
@@ -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 |
@@ -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
|
||||||
Reference in New Issue
Block a user