feat(xml): add imagebutton support to XML (#9381)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Gabor Kiss-Vamosi
2025-12-11 08:01:47 +01:00
committed by GitHub
parent c58eda3d1a
commit cfa983a5f4
9 changed files with 358 additions and 10 deletions
+27
View File
@@ -90,6 +90,33 @@ void lv_imagebutton_set_src(lv_obj_t * obj, lv_imagebutton_state_t state, const
refr_image(obj);
}
void lv_imagebutton_set_src_left(lv_obj_t * obj, lv_imagebutton_state_t state, const void * src_left)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_imagebutton_t * imagebutton = (lv_imagebutton_t *)obj;
update_src_info(&imagebutton->src_left[state], src_left);
refr_image(obj);
}
void lv_imagebutton_set_src_right(lv_obj_t * obj, lv_imagebutton_state_t state, const void * src_right)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_imagebutton_t * imagebutton = (lv_imagebutton_t *)obj;
update_src_info(&imagebutton->src_right[state], src_right);
refr_image(obj);
}
void lv_imagebutton_set_src_mid(lv_obj_t * obj, lv_imagebutton_state_t state, const void * src_mid)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_imagebutton_t * imagebutton = (lv_imagebutton_t *)obj;
update_src_info(&imagebutton->src_mid[state], src_mid);
refr_image(obj);
}
void lv_imagebutton_set_state(lv_obj_t * obj, lv_imagebutton_state_t state)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
+37 -10
View File
@@ -56,7 +56,7 @@ lv_obj_t * lv_imagebutton_create(lv_obj_t * parent);
/**
* Set images for a state of the image button
* @param imagebutton pointer to an image button object
* @param obj pointer to an image button object
* @param state for which state set the new image
* @param src_left pointer to an image source for the left side of the button (a C array or path to
* a file)
@@ -65,16 +65,43 @@ lv_obj_t * lv_imagebutton_create(lv_obj_t * parent);
* @param src_right pointer to an image source for the right side of the button (a C array or path
* to a file)
*/
void lv_imagebutton_set_src(lv_obj_t * imagebutton, lv_imagebutton_state_t state, const void * src_left,
void lv_imagebutton_set_src(lv_obj_t * obj, lv_imagebutton_state_t state, const void * src_left,
const void * src_mid,
const void * src_right);
/**
* Set the left image for a state of the image button
* @param obj pointer to an image button object
* @param state for which state set the new image
* @param src_left pointer to an image source for the left side of the button
* (a C array or path to a file)
*/
void lv_imagebutton_set_src_left(lv_obj_t * obj, lv_imagebutton_state_t state, const void * src_left);
/**
* Set the right image for a state of the image button
* @param obj pointer to an image button object
* @param state for which state set the new image
* @param src_right pointer to an image source for the right side of the button
* (a C array or path to a file)
*/
void lv_imagebutton_set_src_right(lv_obj_t * obj, lv_imagebutton_state_t state, const void * src_right);
/**
* Set the middle image for a state of the image button
* @param obj pointer to an image button object
* @param state for which state set the new image
* @param src_mid pointer to an image source for the middle of the button
* (a C array or path to a file)
*/
void lv_imagebutton_set_src_mid(lv_obj_t * obj, lv_imagebutton_state_t state, const void * src_mid);
/**
* Use this function instead of `lv_obj_add/remove_state` to set a state manually
* @param imagebutton pointer to an image button object
* @param obj pointer to an image button object
* @param state the new state
*/
void lv_imagebutton_set_state(lv_obj_t * imagebutton, lv_imagebutton_state_t state);
void lv_imagebutton_set_state(lv_obj_t * obj, lv_imagebutton_state_t state);
/*=====================
* Getter functions
@@ -82,27 +109,27 @@ void lv_imagebutton_set_state(lv_obj_t * imagebutton, lv_imagebutton_state_t sta
/**
* Get the left image in a given state
* @param imagebutton pointer to an image button object
* @param obj pointer to an image button object
* @param state the state where to get the image (from `lv_button_state_t`) `
* @return pointer to the left image source (a C array or path to a file)
*/
const void * lv_imagebutton_get_src_left(lv_obj_t * imagebutton, lv_imagebutton_state_t state);
const void * lv_imagebutton_get_src_left(lv_obj_t * obj, lv_imagebutton_state_t state);
/**
* Get the middle image in a given state
* @param imagebutton pointer to an image button object
* @param obj pointer to an image button object
* @param state the state where to get the image (from `lv_button_state_t`) `
* @return pointer to the middle image source (a C array or path to a file)
*/
const void * lv_imagebutton_get_src_middle(lv_obj_t * imagebutton, lv_imagebutton_state_t state);
const void * lv_imagebutton_get_src_middle(lv_obj_t * obj, lv_imagebutton_state_t state);
/**
* Get the right image in a given state
* @param imagebutton pointer to an image button object
* @param obj pointer to an image button object
* @param state the state where to get the image (from `lv_button_state_t`) `
* @return pointer to the left image source (a C array or path to a file)
*/
const void * lv_imagebutton_get_src_right(lv_obj_t * imagebutton, lv_imagebutton_state_t state);
const void * lv_imagebutton_get_src_right(lv_obj_t * obj, lv_imagebutton_state_t state);
/*=====================
* Other functions
+10
View File
@@ -39,6 +39,7 @@
#include "parsers/lv_xml_chart_parser.h"
#include "parsers/lv_xml_table_parser.h"
#include "parsers/lv_xml_dropdown_parser.h"
#include "parsers/lv_xml_imagebutton_parser.h"
#include "parsers/lv_xml_roller_parser.h"
#include "parsers/lv_xml_scale_parser.h"
#include "parsers/lv_xml_buttonmatrix_parser.h"
@@ -151,6 +152,15 @@ void lv_xml_init(void)
lv_xml_register_widget("lv_dropdown-list", lv_xml_dropdown_list_create, lv_xml_dropdown_list_apply);
#endif
#if LV_USE_IMAGEBUTTON
lv_xml_register_widget("lv_imagebutton", lv_xml_imagebutton_create, lv_xml_imagebutton_apply);
lv_xml_register_widget("lv_imagebutton-src_left", lv_xml_imagebutton_src_left_create,
lv_xml_imagebutton_src_left_apply);
lv_xml_register_widget("lv_imagebutton-src_right", lv_xml_imagebutton_src_right_create,
lv_xml_imagebutton_src_right_apply);
lv_xml_register_widget("lv_imagebutton-src_mid", lv_xml_imagebutton_src_mid_create, lv_xml_imagebutton_src_mid_apply);
#endif
#if LV_USE_ROLLER
lv_xml_register_widget("lv_roller", lv_xml_roller_create, lv_xml_roller_apply);
#endif
+133
View File
@@ -0,0 +1,133 @@
/**
* @file lv_xml_imagebutton_parser.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_xml_imagebutton_parser.h"
#if LV_USE_XML && LV_USE_IMAGEBUTTON
#include "../../../lvgl.h"
#include "../../../lvgl_private.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static lv_imagebutton_state_t imagebutton_state_to_enum(const char * txt);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void * lv_xml_imagebutton_create(lv_xml_parser_state_t * state, const char ** attrs)
{
LV_UNUSED(attrs);
void * item = lv_imagebutton_create(lv_xml_state_get_parent(state));
return item;
}
void lv_xml_imagebutton_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
void * item = lv_xml_state_get_item(state);
lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/
for(int i = 0; attrs[i]; i += 2) {
const char * name = attrs[i];
const char * value = attrs[i + 1];
if(lv_streq("state", name)) lv_imagebutton_set_state(item, imagebutton_state_to_enum(value));
}
}
void * lv_xml_imagebutton_src_left_create(lv_xml_parser_state_t * state, const char ** attrs)
{
const char * state_str = lv_xml_get_value_of(attrs, "state");
const char * src_str = lv_xml_get_value_of(attrs, "src");
void * item = lv_xml_state_get_parent(state);
lv_imagebutton_set_src_left(item, imagebutton_state_to_enum(state_str),
lv_xml_get_image(&state->scope, src_str));
return item;
}
void lv_xml_imagebutton_src_left_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
LV_UNUSED(state);
LV_UNUSED(attrs);
}
void * lv_xml_imagebutton_src_right_create(lv_xml_parser_state_t * state, const char ** attrs)
{
const char * state_str = lv_xml_get_value_of(attrs, "state");
const char * src_str = lv_xml_get_value_of(attrs, "src");
void * item = lv_xml_state_get_parent(state);
lv_imagebutton_set_src_right(item, imagebutton_state_to_enum(state_str),
lv_xml_get_image(&state->scope, src_str));
return item;
}
void lv_xml_imagebutton_src_right_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
LV_UNUSED(state);
LV_UNUSED(attrs);
}
void * lv_xml_imagebutton_src_mid_create(lv_xml_parser_state_t * state, const char ** attrs)
{
const char * state_str = lv_xml_get_value_of(attrs, "state");
const char * src_str = lv_xml_get_value_of(attrs, "src");
void * item = lv_xml_state_get_parent(state);
lv_imagebutton_set_src_mid(item, imagebutton_state_to_enum(state_str),
lv_xml_get_image(&state->scope, src_str));
return item;
}
void lv_xml_imagebutton_src_mid_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
LV_UNUSED(state);
LV_UNUSED(attrs);
}
/**********************
* STATIC FUNCTIONS
**********************/
static lv_imagebutton_state_t imagebutton_state_to_enum(const char * txt)
{
if(lv_streq("released", txt)) return LV_IMAGEBUTTON_STATE_RELEASED;
if(lv_streq("pressed", txt)) return LV_IMAGEBUTTON_STATE_PRESSED;
if(lv_streq("disabled", txt)) return LV_IMAGEBUTTON_STATE_DISABLED;
if(lv_streq("checked_released", txt)) return LV_IMAGEBUTTON_STATE_CHECKED_RELEASED;
if(lv_streq("checked_pressed", txt)) return LV_IMAGEBUTTON_STATE_CHECKED_PRESSED;
if(lv_streq("checked_disabled", txt)) return LV_IMAGEBUTTON_STATE_CHECKED_DISABLED;
LV_LOG_WARN("%s is an unknown value for imagebutton's imagebutton_state", txt);
return 0; /*Return 0 in lack of a better option. */
}
#endif /* LV_USE_XML */
@@ -0,0 +1,45 @@
/**
* @file lv_xml_imagebutton_parser.h
*
*/
#ifndef LV_XML_IMAGEBUTTON_PARSER_H
#define LV_XML_IMAGEBUTTON_PARSER_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_xml.h"
#if LV_USE_XML && LV_USE_IMAGEBUTTON
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void * lv_xml_imagebutton_create(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_imagebutton_apply(lv_xml_parser_state_t * state, const char ** attrs);
void * lv_xml_imagebutton_src_left_create(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_imagebutton_src_left_apply(lv_xml_parser_state_t * state, const char ** attrs);
void * lv_xml_imagebutton_src_right_create(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_imagebutton_src_right_apply(lv_xml_parser_state_t * state, const char ** attrs);
void * lv_xml_imagebutton_src_mid_create(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_imagebutton_src_mid_apply(lv_xml_parser_state_t * state, const char ** attrs);
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_XML_IMAGEBUTTON_PARSER_H*/
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -0,0 +1,66 @@
#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_imagebutton_with_attrs(void)
{
LV_IMAGE_DECLARE(imagebutton_left);
LV_IMAGE_DECLARE(imagebutton_right);
LV_IMAGE_DECLARE(imagebutton_mid);
lv_xml_register_image(NULL, "img_left", &imagebutton_left);
lv_xml_register_image(NULL, "img_right", &imagebutton_right);
lv_xml_register_image(NULL, "img_mid", &imagebutton_mid);
lv_obj_t * scr = lv_screen_active();
const char * imagebutton_attrs[] = {
"state", "checked_disabled",
"align", "center",
"width", "200",
NULL, NULL,
};
lv_obj_t * imagebutton = lv_xml_create(scr, "lv_imagebutton", imagebutton_attrs);
lv_obj_center(imagebutton);
const char * imagebutton_src_left_attrs[] = {
"state", "checked_disabled",
"src", "img_left",
NULL, NULL,
};
lv_xml_create(imagebutton, "lv_imagebutton-src_left", imagebutton_src_left_attrs);
const char * imagebutton_src_right_attrs[] = {
"state", "checked_disabled",
"src", "img_right",
NULL, NULL,
};
lv_xml_create(imagebutton, "lv_imagebutton-src_right", imagebutton_src_right_attrs);
const char * imagebutton_src_mid_attrs[] = {
"state", "checked_disabled",
"src", "img_mid",
NULL, NULL,
};
lv_xml_create(imagebutton, "lv_imagebutton-src_mid", imagebutton_src_mid_attrs);
TEST_ASSERT_EQUAL_SCREENSHOT("xml/lv_imagebutton.png");
}
#endif
+40
View File
@@ -0,0 +1,40 @@
<!--
<lv_imagebutton state="checked">
<lv_imagebutton-src_left state="released" src="normal_left"/>
<lv_imagebutton-src_mid state="released" src="normal_mid"/>
<lv_imagebutton-src_right state="released" src="normal_right"/>
<lv_imagebutton-src_left state="pressed" src="pr_left"/>
<lv_imagebutton-src_mid state="pressed" src="pr_mid"/>
<lv_imagebutton-src_right state="pressed" src="pr_right"/>
</lv_imagebutton>
-->
<widget>
<api>
<enumdef name="lv_imagebutton_state" help="Possible states of an image button">
<enum name="released" help="Released"/>
<enum name="pressed" help="Pressed"/>
<enum name="disabled" help="Disabled"/>
<enum name="checked_released" help="Checked and released"/>
<enum name="checked_pressed" help="Checked and pressed"/>
<enum name="checked_disabled" help="Checked and disabled"/>
</enumdef>
<prop name="state" type="enum:lv_imagebutton_state" help="The current state of the imagebutton"/>
<element name="src_left" access="set" help="Set the left image source in a given state">
<arg name="state" type="enum:lv_imagebutton_state" help="Set the image in this state"/>
<prop name="src" type="image" help="The image in the given state"/>
</element>
<element name="src_right" access="set" help="Set the right image source in a given state">
<arg name="state" type="enum:lv_imagebutton_state" help="Set the image in this state"/>
<prop name="src" type="image" help="The image in the given state"/>
</element>
<element name="src_mid" access="set" help="Set the middle image source in a given state">
<arg name="state" type="enum:lv_imagebutton_state" help="Set the image in this state"/>
<prop name="src" type="image" help="The image in the given state"/>
</element>
</api>
</widget>