对象创建
1、lv中所有的对象都以obj为基础进行扩展的。创建对象时父对象是空,则在显示器屏链表增加一个节点,父对象非空则在其子链表增加一个节点。创建完成会通过parent->signal_cb(parent, LV_SIGNAL_CHILD_CHG, new_obj)通知父对象。
lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
{
lv_obj_t * new_obj = NULL;
/*Create a screen*/
if(parent == NULL) {
LV_LOG_TRACE("Screen create started");
lv_disp_t * disp = lv_disp_get_default();
if(!disp) {
LV_LOG_WARN("lv_obj_create: not display created to so far. No place to assign the new screen");
return NULL;
}
new_obj = _lv_ll_ins_head(&disp->scr_ll);
LV_ASSERT_MEM(new_obj);
if(new_obj == NULL) return NULL;
_lv_memset_00(new_obj, sizeof(lv_obj_t));
}
/*Create a normal object*/
else {
}
……
/*Init realign*/
#if LV_USE_OBJ_REALIGN
new_obj->realign.align = LV_ALIGN_CENTER;
new_obj->realign.xofs = 0;
new_obj->realign.yofs = 0;
new_obj->realign.base = NULL;
new_obj->realign.auto_realign = 0;//自动对齐关闭
#endif
……
if(copy == NULL) {
if(parent != NULL) lv_theme_apply(new_obj, LV_THEME_OBJ);
else lv_theme_apply(new_obj, LV_THEME_SCR);//设置风格
}
else {
lv_style_list_copy(&new_obj->style_list, ©->style_list);
}
/*Copy the attributes if required*/
if(copy != NULL) {
……
}
/*Send a signal to the parent to notify it about the new child*/
if(parent != NULL) {
parent->signal_cb(parent, LV_SIGNAL_CHILD_CHG, new_obj);
/*Invalidate the area if not screen created*/
lv_obj_invalidate(new_obj);
}
LV_LOG_INFO("Object create ready");
return new_obj;
}
2、obj->coords是对象的绝对(显示)坐标。所以每次更新坐标同时通知子对象,自己,父对象。
void lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
/*Convert x and y to absolute coordinates*/
lv_obj_t * par = obj->parent;
if(par) {
x = x + par->coords.x1;
y = y + par->coords.y1;
}
/*Calculate and set the movement*/
lv_point_t diff;
diff.x = x - obj->coords.x1;
diff.y = y - obj->coords.y1;
/* Do nothing if the position is not changed */
/* It is very important else recursive positioning can
* occur without position change*/
if(diff.x == 0 && diff.y == 0) return;
if(obj->refr == false) return;
/*Invalidate the original area*/
lv_obj_invalidate(obj);
/*Save the original coordinates*/
lv_area_t ori;
lv_obj_get_coords(obj, &ori);
obj->coords.x1 += diff.x;
obj->coords.y1 += diff.y;
obj->coords.x2 += diff.x;
obj->coords.y2 += diff.y;
refresh_children_position(obj, diff.x, diff.y);
/*Inform the object about its new coordinates*/
obj->signal_cb(obj, LV_SIGNAL_COORD_CHG, &ori);
/*Send a signal to the parent too*/
if(par) par->signal_cb(par, LV_SIGNAL_CHILD_CHG, obj);
/*Invalidate the new area*/
lv_obj_invalidate(obj);
}
对象重新对齐
#if LV_USE_OBJ_REALIGN
typedef struct {
const struct _lv_obj_t * base;
lv_coord_t xofs;
lv_coord_t yofs;
lv_align_t align;
uint8_t auto_realign : 1;
uint8_t mid_align : 1; /**< 1: the origo (center of the object) was aligned with
`lv_obj_align_origo`*/
} lv_realign_t;
#endif
两个有用的接口
void lv_obj_realign(lv_obj_t * obj)
void lv_obj_set_auto_realign(lv_obj_t * obj, bool en)