diff --git a/docs/src/details/widgets/bar.rst b/docs/src/details/widgets/bar.rst index 06f98a5e4e..cc02b5e321 100644 --- a/docs/src/details/widgets/bar.rst +++ b/docs/src/details/widgets/bar.rst @@ -73,6 +73,20 @@ The Bar can be one of the following modes: :cpp:expr:`lv_bar_set_start_value(bar, new_value, LV_ANIM_ON/OFF)`. The start value must be smaller than the end value. +Data binding +------------ + +To get familiar with observers, subjects, and data bindings in general visit the +:ref:`Observer ` page. + +This method of subscribing to an integer Subject affects a Bar Widget's integer +value directly. Note that this is a one-way binding (Subject ==> Widget) so when +the subject changes the Bar will be updated too. + +It supports integer and float subjects. + +- :cpp:expr:`lv_bar_bind_value(bar, &subject)` + .. _lv_bar_events: diff --git a/src/widgets/bar/lv_bar.c b/src/widgets/bar/lv_bar.c index 60686131ab..91012061af 100644 --- a/src/widgets/bar/lv_bar.c +++ b/src/widgets/bar/lv_bar.c @@ -14,6 +14,7 @@ #if LV_USE_BAR != 0 #include "../../draw/lv_draw.h" +#include "../../others/observer/lv_observer_private.h" #include "../../misc/lv_assert.h" #include "../../misc/lv_anim_private.h" #include "../../misc/lv_math.h" @@ -58,6 +59,10 @@ static void lv_bar_init_anim(lv_obj_t * bar, lv_bar_anim_t * bar_anim); static void lv_bar_anim(void * bar, int32_t value); static void lv_bar_anim_completed(lv_anim_t * a); +#if LV_USE_OBSERVER + static void bar_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +#endif + /********************** * STATIC VARIABLES **********************/ @@ -249,6 +254,22 @@ bool lv_bar_is_symmetrical(lv_obj_t * obj) bar->start_value == bar->min_value; } +#if LV_USE_OBSERVER +lv_observer_t * lv_bar_bind_value(lv_obj_t * obj, lv_subject_t * subject) +{ + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + + if(subject->type != LV_SUBJECT_TYPE_INT && subject->type != LV_SUBJECT_TYPE_FLOAT) { + LV_LOG_WARN("Incompatible subject type: %d", subject->type); + return NULL; + } + + lv_observer_t * observer = lv_subject_add_observer_obj(subject, bar_value_observer_cb, obj, NULL); + return observer; +} +#endif /*LV_USE_OBSERVER*/ + /********************** * STATIC FUNCTIONS **********************/ @@ -712,4 +733,20 @@ static void lv_bar_init_anim(lv_obj_t * obj, lv_bar_anim_t * bar_anim) bar_anim->anim_state = LV_BAR_ANIM_STATE_INV; } +#if LV_USE_OBSERVER + +static void bar_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + if(subject->type == LV_SUBJECT_TYPE_INT) { + lv_bar_set_value(observer->target, subject->value.num, LV_ANIM_OFF); + } +#if LV_USE_FLOAT + else { + lv_bar_set_value(observer->target, (int32_t)subject->value.float_v, LV_ANIM_OFF); + } +#endif +} + +#endif /*LV_USE_OBSERVER*/ + #endif diff --git a/src/widgets/bar/lv_bar.h b/src/widgets/bar/lv_bar.h index 17a1208ddf..5d34e0a74e 100644 --- a/src/widgets/bar/lv_bar.h +++ b/src/widgets/bar/lv_bar.h @@ -164,6 +164,16 @@ lv_bar_orientation_t lv_bar_get_orientation(lv_obj_t * obj); */ bool lv_bar_is_symmetrical(lv_obj_t * obj); +#if LV_USE_OBSERVER +/** + * Bind an integer or float Subject to a Bar's value. + * @param obj pointer to Bar + * @param subject pointer to Subject + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_bar_bind_value(lv_obj_t * obj, lv_subject_t * subject); +#endif + /********************** * MACROS **********************/ diff --git a/xmls/lv_bar.xml b/xmls/lv_bar.xml index 147d0bef4d..7d948214d2 100644 --- a/xmls/lv_bar.xml +++ b/xmls/lv_bar.xml @@ -33,5 +33,7 @@ Example + + \ No newline at end of file