264 lines
8.6 KiB
C
264 lines
8.6 KiB
C
/**
|
|
* @file lv_obj_id.c
|
|
*
|
|
*/
|
|
|
|
/*********************
|
|
* INCLUDES
|
|
*********************/
|
|
#include "../core/lv_obj.h"
|
|
#include "../stdlib/lv_string.h"
|
|
#include "../misc/lv_utils.h"
|
|
#include "lv_obj_property.h"
|
|
|
|
#if LV_USE_OBJ_PROPERTY
|
|
|
|
/*********************
|
|
* DEFINES
|
|
*********************/
|
|
|
|
/**********************
|
|
* TYPEDEFS
|
|
**********************/
|
|
|
|
typedef void (*lv_property_set_int_t)(lv_obj_t *, int32_t);
|
|
typedef void (*lv_property_set_precise_t)(lv_obj_t *, lv_value_precise_t);
|
|
typedef void (*lv_property_set_color_t)(lv_obj_t *, lv_color_t);
|
|
typedef void (*lv_property_set_point_t)(lv_obj_t *, lv_point_t *);
|
|
typedef void (*lv_property_set_pointer_t)(lv_obj_t *, const void *);
|
|
typedef lv_result_t (*lv_property_setter_t)(lv_obj_t *, lv_prop_id_t, const lv_property_t *);
|
|
|
|
typedef int32_t (*lv_property_get_int_t)(const lv_obj_t *);
|
|
typedef lv_value_precise_t (*lv_property_get_precise_t)(const lv_obj_t *);
|
|
typedef lv_color_t (*lv_property_get_color_t)(const lv_obj_t *);
|
|
typedef lv_point_t (*lv_property_get_point_t)(lv_obj_t *);
|
|
typedef void * (*lv_property_get_pointer_t)(const lv_obj_t *);
|
|
typedef lv_result_t (*lv_property_getter_t)(const lv_obj_t *, lv_prop_id_t, lv_property_t *);
|
|
|
|
/**********************
|
|
* STATIC PROTOTYPES
|
|
**********************/
|
|
|
|
static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * value, bool set);
|
|
static int32_t property_name_compare(const void * ref, const void * element);
|
|
|
|
/**********************
|
|
* STATIC VARIABLES
|
|
**********************/
|
|
|
|
/**********************
|
|
* MACROS
|
|
**********************/
|
|
|
|
/**********************
|
|
* GLOBAL FUNCTIONS
|
|
**********************/
|
|
|
|
lv_result_t lv_obj_set_property(lv_obj_t * obj, const lv_property_t * value)
|
|
{
|
|
LV_ASSERT(obj && value);
|
|
|
|
uint32_t index = LV_PROPERTY_ID_INDEX(value->id);
|
|
if(value->id == LV_PROPERTY_ID_INVALID || index < LV_PROPERTY_STYLE_START || index >= LV_PROPERTY_ID_BUILTIN_LAST) {
|
|
LV_LOG_WARN("Invalid property id set to %p", obj);
|
|
return LV_RESULT_INVALID;
|
|
}
|
|
|
|
if(index < LV_PROPERTY_ID_START) {
|
|
lv_obj_set_local_style_prop(obj, index, value->style, value->selector);
|
|
return LV_RESULT_OK;
|
|
}
|
|
|
|
return obj_property(obj, value->id, (lv_property_t *)value, true);
|
|
}
|
|
|
|
lv_result_t lv_obj_set_properties(lv_obj_t * obj, const lv_property_t * value, uint32_t count)
|
|
{
|
|
for(uint32_t i = 0; i < count; i++) {
|
|
lv_result_t result = lv_obj_set_property(obj, &value[i]);
|
|
if(result != LV_RESULT_OK) {
|
|
return result;
|
|
}
|
|
}
|
|
|
|
return LV_RESULT_OK;
|
|
}
|
|
|
|
lv_property_t lv_obj_get_property(lv_obj_t * obj, lv_prop_id_t id)
|
|
{
|
|
lv_result_t result;
|
|
lv_property_t value;
|
|
|
|
uint32_t index = LV_PROPERTY_ID_INDEX(id);
|
|
if(id == LV_PROPERTY_ID_INVALID || index < LV_PROPERTY_STYLE_START || index >= LV_PROPERTY_ID_BUILTIN_LAST) {
|
|
LV_LOG_WARN("Invalid property id to get from %p", obj);
|
|
value.id = LV_PROPERTY_ID_INVALID;
|
|
value.num = 0;
|
|
return value;
|
|
}
|
|
|
|
if(index < LV_PROPERTY_ID_START) {
|
|
lv_obj_get_local_style_prop(obj, index, &value.style, 0);
|
|
value.id = id;
|
|
value.selector = 0;
|
|
return value;
|
|
}
|
|
|
|
result = obj_property(obj, id, &value, false);
|
|
if(result != LV_RESULT_OK)
|
|
value.id = LV_PROPERTY_ID_INVALID;
|
|
|
|
return value;
|
|
}
|
|
|
|
lv_property_t lv_obj_get_style_property(lv_obj_t * obj, lv_prop_id_t id, uint32_t selector)
|
|
{
|
|
lv_property_t value;
|
|
|
|
if(id == LV_PROPERTY_ID_INVALID || id >= LV_PROPERTY_ID_START) {
|
|
LV_LOG_WARN("invalid style property id %d", id);
|
|
value.id = LV_PROPERTY_ID_INVALID;
|
|
value.num = 0;
|
|
return value;
|
|
}
|
|
|
|
lv_obj_get_local_style_prop(obj, id, &value.style, selector);
|
|
value.id = id;
|
|
value.selector = selector;
|
|
return value;
|
|
}
|
|
|
|
lv_prop_id_t lv_obj_property_get_id(const lv_obj_t * obj, const char * name)
|
|
{
|
|
#if LV_USE_OBJ_PROPERTY_NAME
|
|
const lv_obj_class_t * clz;
|
|
const lv_property_name_t * names;
|
|
lv_property_name_t * found;
|
|
|
|
for(clz = obj->class_p; clz; clz = clz->base_class) {
|
|
names = clz->property_names;
|
|
if(names == NULL) {
|
|
/* try base class*/
|
|
continue;
|
|
}
|
|
|
|
found = _lv_utils_bsearch(name, names, clz->names_count, sizeof(lv_property_name_t), property_name_compare);
|
|
if(found) return found->id;
|
|
}
|
|
|
|
/*Check style property*/
|
|
found = _lv_utils_bsearch(name, lv_style_property_names, sizeof(lv_style_property_names) / sizeof(lv_property_name_t),
|
|
sizeof(lv_property_name_t), property_name_compare);
|
|
if(found) return found->id;
|
|
#else
|
|
LV_UNUSED(obj);
|
|
LV_UNUSED(name);
|
|
LV_UNUSED(property_name_compare);
|
|
#endif
|
|
return LV_PROPERTY_ID_INVALID;
|
|
}
|
|
|
|
/**********************
|
|
* STATIC FUNCTIONS
|
|
**********************/
|
|
|
|
static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * value, bool set)
|
|
{
|
|
const lv_property_ops_t * properties;
|
|
const lv_property_ops_t * prop;
|
|
|
|
const lv_obj_class_t * clz;
|
|
uint32_t index = LV_PROPERTY_ID_INDEX(id);
|
|
|
|
for(clz = obj->class_p ; clz; clz = clz->base_class) {
|
|
properties = clz->properties;
|
|
if(properties == NULL) {
|
|
/* try base class*/
|
|
continue;
|
|
}
|
|
|
|
if(id != LV_PROPERTY_ID_ANY && (index < clz->prop_index_start || index > clz->prop_index_end)) {
|
|
/* try base class*/
|
|
continue;
|
|
}
|
|
|
|
/*Check if there's setter available for this class*/
|
|
for(uint32_t i = 0; i < clz->properties_count; i++) {
|
|
prop = &properties[i];
|
|
|
|
/*pass id and value directly to widget's property method*/
|
|
if(prop->id == LV_PROPERTY_ID_ANY) {
|
|
value->id = prop->id;
|
|
if(set) return ((lv_property_setter_t)prop->setter)(obj, id, value);
|
|
else return ((lv_property_getter_t)prop->getter)(obj, id, value);
|
|
}
|
|
|
|
/*Not this id, check next*/
|
|
if(prop->id != id)
|
|
continue;
|
|
|
|
/*id matched but we got null pointer to functions*/
|
|
if(set ? prop->setter == NULL : prop->getter == NULL) {
|
|
LV_LOG_WARN("NULL %s provided, id: %d", set ? "setter" : "getter", id);
|
|
return LV_RESULT_INVALID;
|
|
}
|
|
|
|
/*Update value id if it's a read*/
|
|
if(!set) value->id = prop->id;
|
|
|
|
switch(LV_PROPERTY_ID_TYPE(prop->id)) {
|
|
case LV_PROPERTY_TYPE_INT: {
|
|
if(set)((lv_property_set_int_t)(prop->setter))(obj, value->num);
|
|
else value->num = ((lv_property_get_int_t)(prop->getter))(obj);
|
|
break;
|
|
}
|
|
case LV_PROPERTY_TYPE_PRECISE: {
|
|
if(set)((lv_property_set_precise_t)(prop->setter))(obj, value->precise);
|
|
else value->precise = ((lv_property_get_precise_t)(prop->getter))(obj);
|
|
break;
|
|
}
|
|
case LV_PROPERTY_TYPE_COLOR: {
|
|
if(set)((lv_property_set_color_t)prop->setter)(obj, value->color);
|
|
else value->color = ((lv_property_get_color_t)(prop->getter))(obj);
|
|
break;
|
|
}
|
|
case LV_PROPERTY_TYPE_POINT: {
|
|
lv_point_t * point = &value->point;
|
|
if(set)((lv_property_set_point_t)(prop->setter))(obj, point);
|
|
else *point = ((lv_property_get_point_t)(prop->getter))(obj);
|
|
break;
|
|
}
|
|
case LV_PROPERTY_TYPE_POINTER:
|
|
case LV_PROPERTY_TYPE_IMGSRC:
|
|
case LV_PROPERTY_TYPE_TEXT:
|
|
case LV_PROPERTY_TYPE_OBJ:
|
|
case LV_PROPERTY_TYPE_DISPLAY:
|
|
case LV_PROPERTY_TYPE_FONT: {
|
|
if(set)((lv_property_set_pointer_t)(prop->setter))(obj, value->ptr);
|
|
else value->ptr = ((lv_property_get_pointer_t)(prop->getter))(obj);
|
|
break;
|
|
}
|
|
default: {
|
|
LV_LOG_WARN("Unknown property id: 0x%08x", prop->id);
|
|
return LV_RESULT_INVALID;
|
|
}
|
|
}
|
|
|
|
return LV_RESULT_OK;
|
|
}
|
|
|
|
/*If no setter found, try base class then*/
|
|
}
|
|
|
|
LV_LOG_WARN("Unknown property id: 0x%08x", id);
|
|
return LV_RESULT_INVALID;
|
|
}
|
|
|
|
static int32_t property_name_compare(const void * ref, const void * element)
|
|
{
|
|
const lv_property_name_t * prop = element;
|
|
return lv_strcmp(ref, prop->name);
|
|
}
|
|
|
|
#endif /*LV_USE_OBJ_PROPERTY*/
|