1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

feat(obj): add funcion to get object index, sibling and child count by type

lv_obj_get_child_count_by_type
lv_obj_get_child_by_type
lv_obj_get_sibling_by_type
This commit is contained in:
Gabor Kiss-Vamosi 2023-11-15 22:18:35 +01:00
parent 5267c0b9f4
commit d90363a8e9
3 changed files with 149 additions and 22 deletions

View File

@ -204,7 +204,6 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_obj_class;
*/
typedef struct {
struct _lv_obj_t ** children; /**< Store the pointer of the children in an array.*/
uint32_t child_cnt; /**< Number of children*/
lv_group_t * group_p;
lv_event_list_t event_list;
@ -213,6 +212,7 @@ typedef struct {
int32_t ext_click_pad; /**< Extra click padding in all direction*/
int32_t ext_draw_size; /**< EXTend the size in every direction for drawing.*/
uint16_t child_cnt; /**< Number of children*/
lv_scrollbar_mode_t scrollbar_mode : 2; /**< How to display scrollbars*/
lv_scroll_snap_t scroll_snap_x : 2; /**< Where to align the snappable children horizontally*/
lv_scroll_snap_t scroll_snap_y : 2; /**< Where to align the snappable children vertically*/

View File

@ -315,30 +315,72 @@ lv_obj_t * lv_obj_get_parent(const lv_obj_t * obj)
return obj->parent;
}
lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, int32_t id)
lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, int32_t idx)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
if(obj->spec_attr == NULL) return NULL;
uint32_t idu;
if(id < 0) {
id = obj->spec_attr->child_cnt + id;
if(id < 0) return NULL;
idu = (uint32_t) id;
if(idx < 0) {
idx = obj->spec_attr->child_cnt + idx;
if(idx < 0) return NULL;
idu = (uint32_t) idx;
}
else {
idu = id;
idu = idx;
}
if(idu >= obj->spec_attr->child_cnt) return NULL;
else return obj->spec_attr->children[id];
else return obj->spec_attr->children[idx];
}
lv_obj_t * lv_obj_get_sibling(const lv_obj_t * obj, int32_t id)
lv_obj_t * lv_obj_get_child_by_type(const lv_obj_t * obj, int32_t idx, const lv_obj_class_t * class_p)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
if(obj->spec_attr == NULL) return NULL;
int32_t i;
int32_t cnt = (int32_t)obj->spec_attr->child_cnt;
if(idx >= 0) {
for(i = 0; i < cnt; i++) {
if(obj->spec_attr->children[i]->class_p == class_p) {
if(idx == 0) return obj->spec_attr->children[i];
else idx--;
}
}
}
else {
idx++; /*-1 means the first child*/
for(i = cnt - 1; i >= 0; i--) {
if(obj->spec_attr->children[i]->class_p == class_p) {
if(idx == 0) return obj->spec_attr->children[i];
else idx++;
}
}
}
return NULL;
}
lv_obj_t * lv_obj_get_sibling(const lv_obj_t * obj, int32_t idx)
{
lv_obj_t * parent = lv_obj_get_parent(obj);
return lv_obj_get_child(parent, (int32_t)lv_obj_get_index(obj) + id);
int32_t sibling_idx = (int32_t)lv_obj_get_index(obj) + idx;
if(sibling_idx < 0) return NULL;
return lv_obj_get_child(parent, sibling_idx);
}
lv_obj_t * lv_obj_get_sibling_by_type(const lv_obj_t * obj, int32_t idx, const lv_obj_class_t * class_p)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_obj_t * parent = lv_obj_get_parent(obj);
int32_t sibling_idx = (int32_t)lv_obj_get_index_by_type(obj, class_p) + idx;
if(sibling_idx < 0) return NULL;
return lv_obj_get_child(parent, sibling_idx);
}
uint32_t lv_obj_get_child_cnt(const lv_obj_t * obj)
@ -348,7 +390,35 @@ uint32_t lv_obj_get_child_cnt(const lv_obj_t * obj)
return obj->spec_attr->child_cnt;
}
uint32_t lv_obj_get_index(const lv_obj_t * obj)
uint32_t lv_obj_get_child_count_by_type(const lv_obj_t * obj, const lv_obj_class_t * class_p)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
if(obj->spec_attr == NULL) return 0;
uint32_t i;
uint32_t cnt = 0;
for(i = 0; i < obj->spec_attr->child_cnt; i++) {
if(obj->spec_attr->children[i]->class_p == class_p) cnt++;
}
return cnt;
}
int32_t lv_obj_get_index(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_obj_t * parent = lv_obj_get_parent(obj);
if(parent == NULL) return 0xFFFFFFFF;
int32_t i = 0;
for(i = 0; i < parent->spec_attr->child_cnt; i++) {
if(parent->spec_attr->children[i] == obj) return i;
}
return -1; /*Shouldn't happen*/
}
int32_t lv_obj_get_index_by_type(const lv_obj_t * obj, const lv_obj_class_t * class_p)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
@ -356,11 +426,17 @@ uint32_t lv_obj_get_index(const lv_obj_t * obj)
if(parent == NULL) return 0xFFFFFFFF;
uint32_t i = 0;
for(i = 0; i < lv_obj_get_child_cnt(parent); i++) {
if(lv_obj_get_child(parent, i) == obj) return i;
uint32_t idx = 0;
for(i = 0; i < parent->spec_attr->child_cnt; i++) {
lv_obj_t * child = parent->spec_attr->children[i];
if(child->class_p == class_p) {
if(child == obj) return idx;
idx++;
}
}
return 0xFFFFFFFF; /*Shouldn't happen*/
/*Can happen if there was no children with the given type*/
return -1;
}
void lv_obj_tree_walk(lv_obj_t * start_obj, lv_obj_tree_walk_cb_t cb, void * user_data)
@ -468,8 +544,8 @@ static void obj_delete_core(lv_obj_t * obj)
}
/*Remove the object from the child list of its parent*/
else {
uint32_t id = lv_obj_get_index(obj);
uint32_t i;
int32_t id = lv_obj_get_index(obj);
uint16_t i;
for(i = id; i < obj->parent->spec_attr->child_cnt - 1; i++) {
obj->parent->spec_attr->children[i] = obj->parent->spec_attr->children[i + 1];
}

View File

@ -129,7 +129,7 @@ struct _lv_obj_t * lv_obj_get_parent(const struct _lv_obj_t * obj);
/**
* Get the child of an object by the child's index.
* @param obj pointer to an object whose child should be get
* @param id the index of the child.
* @param idx the index of the child.
* 0: the oldest (firstly created) child
* 1: the second oldest
* child count-1: the youngest
@ -137,12 +137,28 @@ struct _lv_obj_t * lv_obj_get_parent(const struct _lv_obj_t * obj);
* -2: the second youngest
* @return pointer to the child or NULL if the index was invalid
*/
struct _lv_obj_t * lv_obj_get_child(const struct _lv_obj_t * obj, int32_t id);
struct _lv_obj_t * lv_obj_get_child(const struct _lv_obj_t * obj, int32_t idx);
/**
* Get the child of an object by the child's index. Consider the children only with a given type.
* @param obj pointer to an object whose child should be get
* @param idx the index of the child.
* 0: the oldest (firstly created) child
* 1: the second oldest
* child count-1: the youngest
* -1: the youngest
* -2: the second youngest
* @param class_p the type of the children to check
* @return pointer to the child or NULL if the index was invalid
*/
struct _lv_obj_t * lv_obj_get_child_by_type(const struct _lv_obj_t * obj, int32_t idx,
const struct _lv_obj_class_t * class_p);
/**
* Return a sibling of an object
* @param obj pointer to an object whose sibling should be get
* @param id 0: `obj` itself
* @param idx 0: `obj` itself
* -1: the first older sibling
* -2: the next older sibling
* 1: the first younger sibling
@ -150,7 +166,22 @@ struct _lv_obj_t * lv_obj_get_child(const struct _lv_obj_t * obj, int32_t id);
* etc
* @return pointer to the requested sibling or NULL if there is no such sibling
*/
struct _lv_obj_t * lv_obj_get_sibling(const struct _lv_obj_t * obj, int32_t id);
struct _lv_obj_t * lv_obj_get_sibling(const struct _lv_obj_t * obj, int32_t idx);
/**
* Return a sibling of an object. Consider the siblings only with a given type.
* @param obj pointer to an object whose sibling should be get
* @param idx 0: `obj` itself
* -1: the first older sibling
* -2: the next older sibling
* 1: the first younger sibling
* 2: the next younger sibling
* etc
* @param class_p the type of the children to check
* @return pointer to the requested sibling or NULL if there is no such sibling
*/
struct _lv_obj_t * lv_obj_get_sibling_by_type(const struct _lv_obj_t * obj, int32_t idx,
const struct _lv_obj_class_t * class_p);
/**
* Get the number of children
@ -159,14 +190,34 @@ struct _lv_obj_t * lv_obj_get_sibling(const struct _lv_obj_t * obj, int32_t id);
*/
uint32_t lv_obj_get_child_cnt(const struct _lv_obj_t * obj);
/**
* Get the number of children having a given type.
* @param obj pointer to an object
* @param class_p the type of the children to check
* @return the number of children
*/
uint32_t lv_obj_get_child_count_by_type(const struct _lv_obj_t * obj, const struct _lv_obj_class_t * class_p);
/**
* Get the index of a child.
* @param obj pointer to an object
* @return the child index of the object.
* E.g. 0: the oldest (firstly created child).
* (0xFFFFFFFF if child could not be found or no parent exists)
* (-1 if child could not be found or no parent exists)
*/
uint32_t lv_obj_get_index(const struct _lv_obj_t * obj);
int32_t lv_obj_get_index(const struct _lv_obj_t * obj);
/**
* Get the index of a child. Consider the children only with a given type.
* @param obj pointer to an object
* @param class_p the type of the children to check
* @return the child index of the object.
* E.g. 0: the oldest (firstly created child with the given class).
* (-1 if child could not be found or no parent exists)
*/
int32_t lv_obj_get_index_by_type(const struct _lv_obj_t * obj, const struct _lv_obj_class_t * class_p);
/**
* Iterate through all children of any object.