718 lines
20 KiB
C
718 lines
20 KiB
C
/**
|
|
* @file lv_observer.c
|
|
*
|
|
*/
|
|
|
|
/*********************
|
|
* INCLUDES
|
|
*********************/
|
|
|
|
#include "lv_observer.h"
|
|
#if LV_USE_OBSERVER
|
|
|
|
#include "../../lvgl.h"
|
|
|
|
/*********************
|
|
* DEFINES
|
|
*********************/
|
|
|
|
/**********************
|
|
* TYPEDEFS
|
|
**********************/
|
|
typedef struct {
|
|
uint32_t flag;
|
|
lv_subject_value_t value;
|
|
uint32_t inv : 1;
|
|
} flag_and_cond_t;
|
|
|
|
/**********************
|
|
* STATIC PROTOTYPES
|
|
**********************/
|
|
static void unsubscribe_on_delete_cb(lv_event_t * e);
|
|
static void group_notify_cb(lv_observer_t * observer, lv_subject_t * subject);
|
|
static lv_observer_t * bind_to_bitfield(lv_subject_t * subject, lv_obj_t * obj, lv_observer_cb_t cb, uint32_t flag,
|
|
int32_t ref_value, bool inv);
|
|
static void obj_flag_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
|
|
static void obj_state_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
|
|
|
|
#if LV_USE_BUTTON
|
|
static void btn_value_changed_event_cb(lv_event_t * e);
|
|
#endif
|
|
|
|
#if LV_USE_LABEL
|
|
static void label_text_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
|
|
#endif
|
|
|
|
#if LV_USE_ARC
|
|
static void arc_value_changed_event_cb(lv_event_t * e);
|
|
static void arc_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
|
|
#endif
|
|
|
|
#if LV_USE_SLIDER
|
|
static void slider_value_changed_event_cb(lv_event_t * e);
|
|
static void slider_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
|
|
#endif
|
|
|
|
#if LV_USE_ROLLER
|
|
static void roller_value_changed_event_cb(lv_event_t * e);
|
|
static void roller_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
|
|
#endif
|
|
|
|
#if LV_USE_DROPDOWN
|
|
static void dropdown_value_changed_event_cb(lv_event_t * e);
|
|
static void dropdown_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject);
|
|
#endif
|
|
|
|
/**********************
|
|
* STATIC VARIABLES
|
|
**********************/
|
|
|
|
/**********************
|
|
* MACROS
|
|
**********************/
|
|
|
|
/**********************
|
|
* GLOBAL FUNCTIONS
|
|
**********************/
|
|
|
|
void lv_subject_init_int(lv_subject_t * subject, int32_t value)
|
|
{
|
|
lv_memzero(subject, sizeof(lv_subject_t));
|
|
subject->type = LV_SUBJECT_TYPE_INT;
|
|
subject->value.num = value;
|
|
subject->prev_value.num = value;
|
|
_lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t));
|
|
}
|
|
|
|
void lv_subject_set_int(lv_subject_t * subject, int32_t value)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_INT) {
|
|
LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_INT");
|
|
return;
|
|
}
|
|
|
|
subject->prev_value.num = subject->value.num;
|
|
subject->value.num = value;
|
|
lv_subject_notify(subject);
|
|
}
|
|
|
|
int32_t lv_subject_get_int(lv_subject_t * subject)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_INT) {
|
|
LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_INT");
|
|
return 0;
|
|
}
|
|
|
|
return subject->value.num;
|
|
}
|
|
|
|
int32_t lv_subject_get_previous_int(lv_subject_t * subject)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_INT) {
|
|
LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_INT");
|
|
return 0;
|
|
}
|
|
|
|
return subject->prev_value.num;
|
|
}
|
|
|
|
void lv_subject_init_string(lv_subject_t * subject, char * buf, char * prev_buf, size_t size, const char * value)
|
|
{
|
|
lv_memzero(subject, sizeof(lv_subject_t));
|
|
lv_strncpy(buf, value, size);
|
|
if(prev_buf) lv_strncpy(prev_buf, value, size);
|
|
|
|
subject->type = LV_SUBJECT_TYPE_STRING;
|
|
subject->size = size;
|
|
subject->value.pointer = buf;
|
|
subject->prev_value.pointer = prev_buf;
|
|
|
|
_lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t));
|
|
}
|
|
|
|
void lv_subject_copy_string(lv_subject_t * subject, const char * buf)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_STRING) {
|
|
LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_INT");
|
|
return;
|
|
}
|
|
|
|
if(subject->size < 1) return;
|
|
if(subject->prev_value.pointer) {
|
|
lv_strncpy((char *)subject->prev_value.pointer, subject->value.pointer, subject->size - 1);
|
|
}
|
|
|
|
lv_strncpy((char *)subject->value.pointer, buf, subject->size - 1);
|
|
|
|
lv_subject_notify(subject);
|
|
|
|
}
|
|
|
|
const char * lv_subject_get_string(lv_subject_t * subject)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_STRING) {
|
|
LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_STRING");
|
|
return "";
|
|
}
|
|
|
|
return subject->value.pointer;
|
|
}
|
|
|
|
const char * lv_subject_get_previous_string(lv_subject_t * subject)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_STRING) {
|
|
LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_STRING");
|
|
return NULL;
|
|
}
|
|
|
|
return subject->prev_value.pointer;
|
|
}
|
|
|
|
void lv_subject_init_pointer(lv_subject_t * subject, void * value)
|
|
{
|
|
lv_memzero(subject, sizeof(lv_subject_t));
|
|
subject->type = LV_SUBJECT_TYPE_POINTER;
|
|
subject->value.pointer = value;
|
|
subject->prev_value.pointer = value;
|
|
_lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t));
|
|
}
|
|
|
|
void lv_subject_set_pointer(lv_subject_t * subject, void * ptr)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_POINTER) {
|
|
LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_POINTER");
|
|
return;
|
|
}
|
|
|
|
subject->prev_value.pointer = subject->value.pointer;
|
|
subject->value.pointer = ptr;
|
|
lv_subject_notify(subject);
|
|
}
|
|
|
|
const void * lv_subject_get_pointer(lv_subject_t * subject)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_POINTER) {
|
|
LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_POINTER");
|
|
return NULL;
|
|
}
|
|
|
|
return subject->value.pointer;
|
|
}
|
|
|
|
const void * lv_subject_get_previous_pointer(lv_subject_t * subject)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_POINTER) {
|
|
LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_POINTER");
|
|
return NULL;
|
|
}
|
|
|
|
return subject->prev_value.pointer;
|
|
}
|
|
|
|
void lv_subject_init_color(lv_subject_t * subject, lv_color_t color)
|
|
{
|
|
lv_memzero(subject, sizeof(lv_subject_t));
|
|
subject->type = LV_SUBJECT_TYPE_COLOR;
|
|
subject->value.color = color;
|
|
subject->prev_value.color = color;
|
|
_lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t));
|
|
}
|
|
|
|
void lv_subject_set_color(lv_subject_t * subject, lv_color_t color)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_COLOR) {
|
|
LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_COLOR");
|
|
return;
|
|
}
|
|
|
|
subject->prev_value.color = subject->value.color;
|
|
subject->value.color = color;
|
|
lv_subject_notify(subject);
|
|
}
|
|
|
|
lv_color_t lv_subject_get_color(lv_subject_t * subject)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_COLOR) {
|
|
LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_COLOR");
|
|
return lv_color_black();
|
|
}
|
|
|
|
return subject->value.color;
|
|
}
|
|
|
|
lv_color_t lv_subject_get_previous_color(lv_subject_t * subject)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_COLOR) {
|
|
LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_COLOR");
|
|
return lv_color_black();
|
|
}
|
|
|
|
return subject->prev_value.color;
|
|
}
|
|
|
|
void lv_subject_init_group(lv_subject_t * subject, lv_subject_t * list[], uint32_t list_len)
|
|
{
|
|
subject->type = LV_SUBJECT_TYPE_GROUP;
|
|
subject->size = list_len;
|
|
_lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t));
|
|
subject->value.pointer = list;
|
|
|
|
/* bind all subjects to this subject */
|
|
uint32_t i;
|
|
for(i = 0; i < list_len; i++) {
|
|
/*If a subject in the group changes notify the group itself*/
|
|
lv_subject_add_observer(list[i], group_notify_cb, subject);
|
|
}
|
|
}
|
|
|
|
lv_subject_t * lv_subject_get_group_element(lv_subject_t * subject, int32_t index)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_GROUP) {
|
|
LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_GROUP");
|
|
return NULL;
|
|
}
|
|
|
|
if(index >= subject->size) return NULL;
|
|
|
|
return ((lv_subject_t **)(subject->value.pointer))[index];
|
|
}
|
|
|
|
lv_observer_t * lv_subject_add_observer(lv_subject_t * subject, lv_observer_cb_t cb, void * user_data)
|
|
{
|
|
lv_observer_t * observer = lv_subject_add_observer_obj(subject, cb, NULL, user_data);
|
|
return observer;
|
|
}
|
|
|
|
lv_observer_t * lv_subject_add_observer_obj(lv_subject_t * subject, lv_observer_cb_t cb, lv_obj_t * obj,
|
|
void * user_data)
|
|
{
|
|
LV_ASSERT_NULL(subject);
|
|
if(subject->type == LV_SUBJECT_TYPE_INVALID) {
|
|
LV_LOG_WARN("Subject not initialized yet");
|
|
return NULL;
|
|
}
|
|
lv_observer_t * observer = _lv_ll_ins_tail(&(subject->subs_ll));
|
|
LV_ASSERT_MALLOC(observer);
|
|
if(observer == NULL) return NULL;
|
|
|
|
lv_memzero(observer, sizeof(*observer));
|
|
|
|
observer->subject = subject;
|
|
observer->cb = cb;
|
|
observer->user_data = user_data;
|
|
observer->target = obj;
|
|
/* subscribe to delete event of the object */
|
|
if(obj != NULL) {
|
|
lv_obj_add_event_cb(obj, unsubscribe_on_delete_cb, LV_EVENT_DELETE, observer);
|
|
}
|
|
|
|
/* update object immediately */
|
|
if(observer->cb) observer->cb(observer, subject);
|
|
|
|
return observer;
|
|
}
|
|
|
|
lv_observer_t * lv_subject_add_observer_with_target(lv_subject_t * subject, lv_observer_cb_t cb, void * target,
|
|
void * user_data)
|
|
{
|
|
LV_ASSERT_NULL(subject);
|
|
if(subject->type == LV_SUBJECT_TYPE_INVALID) {
|
|
LV_LOG_WARN("Subject not initialized yet");
|
|
return NULL;
|
|
}
|
|
lv_observer_t * observer = _lv_ll_ins_tail(&(subject->subs_ll));
|
|
LV_ASSERT_MALLOC(observer);
|
|
if(observer == NULL) return NULL;
|
|
|
|
lv_memzero(observer, sizeof(*observer));
|
|
|
|
observer->subject = subject;
|
|
observer->cb = cb;
|
|
observer->user_data = user_data;
|
|
observer->target = target;
|
|
|
|
/* update object immediately */
|
|
if(observer->cb) observer->cb(observer, subject);
|
|
|
|
return observer;
|
|
}
|
|
|
|
void lv_observer_remove(lv_observer_t * observer)
|
|
{
|
|
LV_ASSERT_NULL(observer);
|
|
|
|
observer->subject->notify_restart_query = 1;
|
|
|
|
_lv_ll_remove(&(observer->subject->subs_ll), observer);
|
|
|
|
if(observer->auto_free_user_data) {
|
|
lv_free(observer->user_data);
|
|
}
|
|
lv_free(observer);
|
|
}
|
|
|
|
void lv_subject_remove_all_obj(lv_subject_t * subject, lv_obj_t * obj)
|
|
{
|
|
LV_ASSERT_NULL(subject);
|
|
if(subject->type == LV_SUBJECT_TYPE_INVALID) {
|
|
LV_LOG_WARN("Subject not initialized yet");
|
|
return;
|
|
}
|
|
|
|
while(lv_obj_remove_event_cb(obj, unsubscribe_on_delete_cb));
|
|
|
|
#if LV_USE_BUTTON
|
|
while(lv_obj_remove_event_cb(obj, btn_value_changed_event_cb));
|
|
#endif /*LV_USE_BUTTON*/
|
|
|
|
#if LV_USE_ARC
|
|
while(lv_obj_remove_event_cb(obj, arc_value_changed_event_cb));
|
|
#endif /*LV_USE_ARC*/
|
|
|
|
#if LV_USE_ROLLER
|
|
while(lv_obj_remove_event_cb(obj, roller_value_changed_event_cb));
|
|
#endif /*LV_USE_ROLLER*/
|
|
|
|
#if LV_USE_DROPDOWN
|
|
while(lv_obj_remove_event_cb(obj, dropdown_value_changed_event_cb));
|
|
#endif /*LV_USE_DROPDOWN*/
|
|
|
|
lv_observer_t * observer = _lv_ll_get_head(&subject->subs_ll);
|
|
while(observer) {
|
|
lv_observer_t * observer_next = _lv_ll_get_next(&subject->subs_ll, observer);
|
|
if(observer->target == obj) {
|
|
lv_observer_remove(observer);
|
|
}
|
|
observer = observer_next;
|
|
}
|
|
}
|
|
|
|
void * lv_observer_get_target(lv_observer_t * observer)
|
|
{
|
|
LV_ASSERT_NULL(observer);
|
|
|
|
return observer->target;
|
|
}
|
|
|
|
void lv_subject_notify(lv_subject_t * subject)
|
|
{
|
|
LV_ASSERT_NULL(subject);
|
|
|
|
lv_observer_t * observer;
|
|
_LV_LL_READ(&(subject->subs_ll), observer) {
|
|
observer->notified = 0;
|
|
}
|
|
|
|
do {
|
|
subject->notify_restart_query = 0;
|
|
_LV_LL_READ(&(subject->subs_ll), observer) {
|
|
if(observer->cb && observer->notified == 0) {
|
|
observer->cb(observer, subject);
|
|
if(subject->notify_restart_query) break;
|
|
observer->notified = 1;
|
|
}
|
|
}
|
|
} while(subject->notify_restart_query);
|
|
}
|
|
|
|
lv_observer_t * lv_obj_bind_flag_if_eq(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value)
|
|
{
|
|
lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, false);
|
|
return observable;
|
|
}
|
|
|
|
lv_observer_t * lv_obj_bind_flag_if_not_eq(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag,
|
|
int32_t ref_value)
|
|
{
|
|
lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, true);
|
|
return observable;
|
|
}
|
|
|
|
lv_observer_t * lv_obj_bind_state_if_eq(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value)
|
|
{
|
|
lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, false);
|
|
return observable;
|
|
}
|
|
|
|
lv_observer_t * lv_obj_bind_state_if_not_eq(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value)
|
|
{
|
|
lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, true);
|
|
return observable;
|
|
}
|
|
|
|
#if LV_USE_BUTTON
|
|
lv_observer_t * lv_button_bind_checked(lv_obj_t * obj, lv_subject_t * subject)
|
|
{
|
|
lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, LV_STATE_CHECKED, 1, false);
|
|
lv_obj_add_event_cb(obj, btn_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject);
|
|
return observable;
|
|
}
|
|
#endif /*LV_USE_BUTTON*/
|
|
|
|
#if LV_USE_LABEL
|
|
lv_observer_t * lv_label_bind_text(lv_obj_t * obj, lv_subject_t * subject, const char * fmt)
|
|
{
|
|
if(fmt == NULL) {
|
|
if(subject->type != LV_SUBJECT_TYPE_STRING && subject->type != LV_SUBJECT_TYPE_POINTER) {
|
|
LV_LOG_WARN("Incompatible subject type: %d", subject->type);
|
|
return NULL;
|
|
}
|
|
}
|
|
else {
|
|
if(subject->type != LV_SUBJECT_TYPE_STRING && subject->type != LV_SUBJECT_TYPE_POINTER &&
|
|
subject->type != LV_SUBJECT_TYPE_INT) {
|
|
LV_LOG_WARN("Incompatible subject type: %d", subject->type);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
lv_observer_t * observer = lv_subject_add_observer_obj(subject, label_text_observer_cb, obj, (void *)fmt);
|
|
return observer;
|
|
}
|
|
#endif /*LV_USE_LABEL*/
|
|
|
|
#if LV_USE_ARC
|
|
lv_observer_t * lv_arc_bind_value(lv_obj_t * obj, lv_subject_t * subject)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_INT) {
|
|
LV_LOG_WARN("Incompatible subject type: %d", subject->type);
|
|
return NULL;
|
|
}
|
|
|
|
lv_obj_add_event_cb(obj, arc_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject);
|
|
|
|
lv_observer_t * observer = lv_subject_add_observer_obj(subject, arc_value_observer_cb, obj, NULL);
|
|
return observer;
|
|
}
|
|
#endif /*LV_USE_ARC*/
|
|
|
|
#if LV_USE_SLIDER
|
|
lv_observer_t * lv_slider_bind_value(lv_obj_t * obj, lv_subject_t * subject)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_INT) {
|
|
LV_LOG_WARN("Incompatible subject type: %d", subject->type);
|
|
return NULL;
|
|
}
|
|
|
|
lv_obj_add_event_cb(obj, slider_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject);
|
|
|
|
lv_observer_t * observer = lv_subject_add_observer_obj(subject, slider_value_observer_cb, obj, NULL);
|
|
return observer;
|
|
}
|
|
#endif /*LV_USE_SLIDER*/
|
|
|
|
#if LV_USE_ROLLER
|
|
|
|
lv_observer_t * lv_roller_bind_value(lv_obj_t * obj, lv_subject_t * subject)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_INT) {
|
|
LV_LOG_WARN("Incompatible subject type: %d", subject->type);
|
|
return NULL;
|
|
}
|
|
|
|
lv_obj_add_event_cb(obj, roller_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject);
|
|
|
|
lv_observer_t * observer = lv_subject_add_observer_obj(subject, roller_value_observer_cb, obj, NULL);
|
|
return observer;
|
|
|
|
}
|
|
#endif /*LV_USE_ROLLER*/
|
|
|
|
#if LV_USE_DROPDOWN
|
|
|
|
lv_observer_t * lv_dropdown_bind_value(lv_obj_t * obj, lv_subject_t * subject)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_INT) {
|
|
LV_LOG_WARN("Incompatible subject type: %d", subject->type);
|
|
return NULL;
|
|
}
|
|
|
|
lv_obj_add_event_cb(obj, dropdown_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject);
|
|
|
|
lv_observer_t * observer = lv_subject_add_observer_obj(subject, dropdown_value_observer_cb, obj, NULL);
|
|
return observer;
|
|
|
|
}
|
|
|
|
#endif /*LV_USE_DROPDOWN*/
|
|
|
|
/**********************
|
|
* STATIC FUNCTIONS
|
|
**********************/
|
|
|
|
static void group_notify_cb(lv_observer_t * observer, lv_subject_t * subject)
|
|
{
|
|
LV_UNUSED(subject);
|
|
lv_subject_t * subject_group = observer->user_data;
|
|
lv_subject_notify(subject_group);
|
|
}
|
|
|
|
static void unsubscribe_on_delete_cb(lv_event_t * e)
|
|
{
|
|
lv_observer_t * observer = lv_event_get_user_data(e);
|
|
lv_observer_remove(observer);
|
|
}
|
|
|
|
static lv_observer_t * bind_to_bitfield(lv_subject_t * subject, lv_obj_t * obj, lv_observer_cb_t cb, uint32_t flag,
|
|
int32_t ref_value, bool inv)
|
|
{
|
|
if(subject->type != LV_SUBJECT_TYPE_INT) {
|
|
LV_LOG_WARN("Incompatible subject type: %d", subject->type);
|
|
return NULL;
|
|
}
|
|
|
|
flag_and_cond_t * p = lv_malloc(sizeof(flag_and_cond_t));
|
|
if(p == NULL) {
|
|
LV_LOG_WARN("Out of memory");
|
|
return NULL;
|
|
}
|
|
|
|
p->flag = flag;
|
|
p->value.num = ref_value;
|
|
p->inv = inv;
|
|
|
|
lv_observer_t * observable = lv_subject_add_observer_obj(subject, cb, obj, p);
|
|
observable->auto_free_user_data = 1;
|
|
return observable;
|
|
}
|
|
|
|
static void obj_flag_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
|
|
{
|
|
flag_and_cond_t * p = observer->user_data;
|
|
|
|
bool res = subject->value.num == p->value.num;
|
|
if(p->inv) res = !res;
|
|
|
|
if(res) {
|
|
lv_obj_add_flag(observer->target, p->flag);
|
|
}
|
|
else {
|
|
lv_obj_remove_flag(observer->target, p->flag);
|
|
}
|
|
}
|
|
|
|
static void obj_state_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
|
|
{
|
|
flag_and_cond_t * p = observer->user_data;
|
|
|
|
bool res = subject->value.num == p->value.num;
|
|
if(p->inv) res = !res;
|
|
|
|
if(res) {
|
|
lv_obj_add_state(observer->target, p->flag);
|
|
}
|
|
else {
|
|
lv_obj_remove_state(observer->target, p->flag);
|
|
}
|
|
}
|
|
|
|
#if LV_USE_BUTTON
|
|
|
|
static void btn_value_changed_event_cb(lv_event_t * e)
|
|
{
|
|
lv_obj_t * obj = lv_event_get_current_target(e);
|
|
lv_subject_t * subject = lv_event_get_user_data(e);
|
|
|
|
lv_subject_set_int(subject, lv_obj_has_state(obj, LV_STATE_CHECKED));
|
|
}
|
|
|
|
#endif /*LV_USE_BUTTON*/
|
|
|
|
#if LV_USE_LABEL
|
|
|
|
static void label_text_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
|
|
{
|
|
const char * fmt = observer->user_data;
|
|
|
|
if(fmt == NULL) {
|
|
lv_label_set_text(observer->target, subject->value.pointer);
|
|
}
|
|
else {
|
|
switch(subject->type) {
|
|
case LV_SUBJECT_TYPE_INT:
|
|
lv_label_set_text_fmt(observer->target, fmt, subject->value.num);
|
|
break;
|
|
case LV_SUBJECT_TYPE_STRING:
|
|
case LV_SUBJECT_TYPE_POINTER:
|
|
lv_label_set_text_fmt(observer->target, fmt, subject->value.pointer);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif /*LV_USE_LABEL*/
|
|
|
|
#if LV_USE_ARC
|
|
|
|
static void arc_value_changed_event_cb(lv_event_t * e)
|
|
{
|
|
lv_obj_t * arc = lv_event_get_current_target(e);
|
|
lv_subject_t * subject = lv_event_get_user_data(e);
|
|
|
|
lv_subject_set_int(subject, lv_arc_get_value(arc));
|
|
}
|
|
|
|
static void arc_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
|
|
{
|
|
lv_arc_set_value(observer->target, subject->value.num);
|
|
}
|
|
|
|
#endif /*LV_USE_ARC*/
|
|
|
|
#if LV_USE_SLIDER
|
|
|
|
static void slider_value_changed_event_cb(lv_event_t * e)
|
|
{
|
|
lv_obj_t * slider = lv_event_get_current_target(e);
|
|
lv_subject_t * subject = lv_event_get_user_data(e);
|
|
|
|
lv_subject_set_int(subject, lv_slider_get_value(slider));
|
|
}
|
|
|
|
static void slider_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
|
|
{
|
|
lv_slider_set_value(observer->target, subject->value.num, LV_ANIM_OFF);
|
|
}
|
|
|
|
#endif /*LV_USE_SLIDER*/
|
|
|
|
#if LV_USE_ROLLER
|
|
|
|
static void roller_value_changed_event_cb(lv_event_t * e)
|
|
{
|
|
lv_obj_t * roller = lv_event_get_current_target(e);
|
|
lv_subject_t * subject = lv_event_get_user_data(e);
|
|
|
|
lv_subject_set_int(subject, lv_roller_get_selected(roller));
|
|
}
|
|
|
|
static void roller_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
|
|
{
|
|
if((int32_t)lv_roller_get_selected(observer->target) != subject->value.num) {
|
|
lv_roller_set_selected(observer->target, subject->value.num, LV_ANIM_OFF);
|
|
}
|
|
}
|
|
|
|
#endif /*LV_USE_ROLLER*/
|
|
|
|
#if LV_USE_DROPDOWN
|
|
|
|
static void dropdown_value_changed_event_cb(lv_event_t * e)
|
|
{
|
|
lv_obj_t * dropdown = lv_event_get_current_target(e);
|
|
lv_subject_t * subject = lv_event_get_user_data(e);
|
|
|
|
lv_subject_set_int(subject, lv_dropdown_get_selected(dropdown));
|
|
}
|
|
|
|
static void dropdown_value_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
|
|
{
|
|
lv_dropdown_set_selected(observer->target, subject->value.num);
|
|
}
|
|
|
|
#endif /*LV_USE_DROPDOWN*/
|
|
|
|
#endif /*LV_USE_OBSERVER*/
|