feat(image): add data binding to image src

This commit is contained in:
Gabor Kiss-Vamosi
2025-09-02 13:00:00 +02:00
parent 9bddc816a2
commit d33320b7e5
5 changed files with 70 additions and 11 deletions
+4 -4
View File
@@ -200,13 +200,13 @@ Data binding
To get familiar with observers, subjects, and data bindings in general visit the
:ref:`Observer <observer_how_to_use>` page.
This method of subscribing to a pointer Subject affects an Image Widget's source (``src``)
This method of subscribing to a pointer Subject affects a Image Widget's source (``src``)
value directly. Note that this is a one-way binding (Subject ==> Widget) so when
the subject changes the Image will be update too.
the subject changes, the Image will be updated too.
It support only pointer subjects.
It supports only pointer subjects.
- :cpp:expr:`lv_image_bind_src(slider, &subject)`
- :cpp:expr:`lv_image_bind_src(img, &subject)`
.. _lv_image_events:
+15 -6
View File
@@ -61,12 +61,21 @@ void lv_xml_image_apply(lv_xml_parser_state_t * state, const char ** attrs)
const char * value = attrs[i + 1];
if(lv_streq("src", name)) lv_image_set_src(item, lv_xml_get_image(&state->scope, 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));
if(lv_streq("scale_y", name)) lv_image_set_scale_y(item, lv_xml_atoi(value));
if(lv_streq("pivot_x", name)) lv_image_set_pivot_x(item, lv_xml_to_size(value));
if(lv_streq("pivot_y", name)) lv_image_set_pivot_y(item, lv_xml_to_size(value));
else if(lv_streq("inner_align", name)) lv_image_set_inner_align(item, image_align_to_enum(value));
else if(lv_streq("rotation", name)) lv_image_set_rotation(item, lv_xml_atoi(value));
else if(lv_streq("scale_x", name)) lv_image_set_scale_x(item, lv_xml_atoi(value));
else if(lv_streq("scale_y", name)) lv_image_set_scale_y(item, lv_xml_atoi(value));
else if(lv_streq("pivot_x", name)) lv_image_set_pivot_x(item, lv_xml_to_size(value));
else if(lv_streq("pivot_y", name)) lv_image_set_pivot_y(item, lv_xml_to_size(value));
else if(lv_streq("bind_src", name)) {
lv_subject_t * subject = lv_xml_get_subject(&state->scope, value);
if(subject) {
lv_image_bind_src(item, subject);
}
else {
LV_LOG_WARN("Subject \"%s\" doesn't exist in image bind_src", value);
}
}
}
}
+38 -1
View File
@@ -13,8 +13,9 @@
#include "../../draw/lv_draw_private.h"
#include "../../core/lv_obj_event_private.h"
#include "../../core/lv_obj_class_private.h"
#include "../../core/lv_obj_class_private.h"
#include "../../core/lv_obj_draw_private.h"
#include "../../core/lv_obj_class_private.h"
#include "../../others/observer/lv_observer_private.h"
#if LV_USE_IMAGE != 0
@@ -39,6 +40,11 @@ static void draw_image(lv_event_t * e);
static void scale_update(lv_obj_t * obj, int32_t scale_x, int32_t scale_y);
static void update_align(lv_obj_t * obj);
static void reset_image_attributes(lv_obj_t * obj);
#if LV_USE_OBSERVER
static void image_src_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
#endif /*LV_USE_OBSERVER*/
#if LV_USE_OBJ_PROPERTY
static void lv_image_set_pivot_helper(lv_obj_t * obj, lv_point_t * pivot);
static lv_point_t lv_image_get_pivot_helper(lv_obj_t * obj);
@@ -653,6 +659,24 @@ const lv_image_dsc_t * lv_image_get_bitmap_map_src(lv_obj_t * obj)
return img->bitmap_mask_src;
}
#if LV_USE_OBSERVER
lv_observer_t * lv_image_bind_src(lv_obj_t * obj, lv_subject_t * subject)
{
LV_ASSERT_NULL(subject);
LV_ASSERT_OBJ(obj, MY_CLASS);
if(subject->type != LV_SUBJECT_TYPE_POINTER) {
LV_LOG_WARN("Incompatible subject type: %d", subject->type);
return NULL;
}
lv_observer_t * observer = lv_subject_add_observer_obj(subject, image_src_observer_cb, obj, NULL);
return observer;
}
#endif /*LV_USE_OBSERVER*/
/**********************
* STATIC FUNCTIONS
**********************/
@@ -1035,6 +1059,18 @@ static void reset_image_attributes(lv_obj_t * obj)
lv_obj_refresh_self_size(obj);
}
#if LV_USE_OBSERVER
static void image_src_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
{
if(subject->type == LV_SUBJECT_TYPE_POINTER) {
lv_image_set_src(observer->target, subject->value.pointer);
}
}
#endif /*LV_USE_OBSERVER*/
#if LV_USE_OBJ_PROPERTY
static void lv_image_set_pivot_helper(lv_obj_t * obj, lv_point_t * pivot)
{
@@ -1049,4 +1085,5 @@ static lv_point_t lv_image_get_pivot_helper(lv_obj_t * obj)
}
#endif
#endif
+12
View File
@@ -25,6 +25,7 @@ extern "C" {
#include "../../core/lv_obj.h"
#include "../../misc/lv_fs.h"
#include "../../draw/lv_draw.h"
#include "../../others/observer/lv_observer.h"
/*********************
* DEFINES
@@ -338,6 +339,17 @@ lv_image_align_t lv_image_get_inner_align(lv_obj_t * obj);
*/
const lv_image_dsc_t * lv_image_get_bitmap_map_src(lv_obj_t * obj);
#if LV_USE_OBSERVER
/**
* Bind a pointer Subject to an Image's source.
* @param obj pointer to Image
* @param subject pointer to Subject
* @return pointer to newly-created Observer
*/
lv_observer_t * lv_image_bind_src(lv_obj_t * obj, lv_subject_t * subject);
#endif
/**********************
* MACROS
**********************/
+1
View File
@@ -29,5 +29,6 @@ Example
<prop name="scale_y" type="int" help=""/>
<prop name="pivot_x" type="int" help=""/>
<prop name="pivot_y" type="int" help=""/>
<prop name="bind_src" type="subject" />
</api>
</widget>