lvgl:对象obj

发布时间 2023-08-24 19:22:02作者: caesura_k

1 对象 object

  1.1 对象 lv_obj_t 

    对象object:构建用户界面的基本单位,也称之为控件widgets;对于button,label,image,list等组件都可称之为对象;

//lv_obj.h  对象结构体;
typedef struct _lv_obj_t {
    const lv_obj_class_t *class_p;
    struct _lv_obj_t *parent;
    _lv_obj_spec_attr_t *spec_attr;
    _lv_obj_style_t *styles;
#if LV_USE_USER_DATA
    void *user_data;
#endif
    lv_area_t coords;
    lv_obj_flag_t flags;
    lv_state_t state;
    uint16_t layout_inv : 1;
    uint16_t scr_layout_inv : 1;
    uint16_t skip_trans : 1;
    uint16_t style_cnt  : 6;
    uint16_t h_layout   : 1;
    uint16_t w_layout   : 1;
} lv_obj_t;

    1.2 对象属性

      1.2.1 基本属性 basic attributes

        所有对象共享一些基本属性,如position,size,parent,styles,event handlers等等,可对其进行设置/获取,举例如下;

//obj的pos,class,style,draw,scroll属性等都有自己的xx.c和xx.h,可见obj的重要;
//lv_obj_pos.h
void lv_obj_set_pos(struct _lv_obj_t *obj, lv_coord_t x, lv_coord_t y);
void lv_obj_set_size(struct _lv_obj_t *obj, lv_coord_t w, lv_coord_t h);
lv_coord_t lv_obj_get_width(const struct _lv_obj_t *obj);

//lv_obj_styles.h
void lv_obj_add_style(struct _lv_obj_t *obj, lv_style_t *style, lv_style_selector_t selector);
void lv_obj_refresh_style(struct _lv_obj_t *obj, lv_part_t part, lv_style_prop_t prop);

      1.2.2 特定属性 specific attributes

        一些对象拥有一些自己的特殊属性,所以一些对象也会拥有属于自己的特殊函数;

//lv_slider.h  位于widgets/下
static inline void lv_slider_set_range(lv_obj_t *obj, int32_t min, int32_t max);
static inline void lv_slider_set_value(lv_obj_t *obj, int32_t value, lv_anim_enable_t anim);
    

      1.2.3 父对象

        每个对象只允许有一个父对象,父对象可视为子对象的容器,但是父对象可以允许有多个子对象;

        每个子对象只有在父对象范围内可见,超出部分不可见;子对象会随着父对象的移动而移动;

lv_obj_t * parent = lv_obj_create(lv_scr_act());    /*Create a parent object on the current screen*/
lv_obj_set_size(parent, 100, 80);                   /*Set the size of the parent*/

lv_obj_t * obj1 = lv_obj_create(parent);            /*Create an object on the previously created parent object*/
lv_obj_set_pos(obj1, 10, 10);	                    /*Set the position of the new object*/
//lv_obj.c  lv_obj_create()

   1.3 创建/删除对象

/**    //lv_obj.h
 * Create a base object (a rectangle)
 * @param parent    pointer to a parent object. If NULL then a screen will be created.
 * @return          pointer to the new object
 */
lv_obj_t *lv_obj_create(lv_obj_t *parent);



/**    //lv_obj_tree.h
 * Delete an object and all of its children.
 * Also remove the objects from their group and remove all animations (if any).
 * Send `LV_EVENT_DELETED` to deleted objects.
 * @param obj       pointer to an object
 */
void lv_obj_del(struct _lv_obj_t *obj);

/**    //lv_obj_tree.h
 * Helper function for asynchronously deleting objects.
 * Useful for cases where you can't delete an object directly in an `LV_EVENT_DELETE` handler (i.e. parent).
 * @param obj       object to delete
 * @see lv_async_call  cae在lv_timer周期性回调的时候来删除对象,通常是1ms之后删除,看tick;
 */
void lv_obj_del_async(struct _lv_obj_t *obj);

/**    //lv_obj_tree.h
 * Delete all children of an object.
 * Also remove the objects from their group and remove all animations (if any).
 * Send `LV_EVENT_DELETED` to deleted objects.
 * @param obj       pointer to an object
 */
void lv_obj_clean(struct _lv_obj_t *obj);

2 屏幕 screen

  屏幕属于没有parent的obj,屏幕本身也还是obj,可以用创建obj的方式来创建屏幕;

  大约屏幕没啥内容,但是呢又很常见无处不在,屏幕本身也还是obj,所以lvgl把屏幕也概括在了obj章节里;

//对象在创建的时候如果还没有创建好屏幕,那么对象也可以作为屏幕;
lv_obj_t * scr1 = lv_obj_create(NULL);

/**    //lv_disp.h  
 * Get the active screen of the default display
 * @return pointer to the active screen
 */
static inline lv_obj_t * lv_scr_act(void)
{
    return lv_disp_get_scr_act(lv_disp_get_default());
}

/**    //lv_disp.h
 * Make a screen active
 * @param scr pointer to a screen
 */
static inline void lv_scr_load(lv_obj_t * scr)
{
    lv_disp_load_scr(scr);
}

   2.1 层 layers

    对于屏幕而言,每个屏幕上都有两层layer,分别是top layer和system layer;

    top layer位于所有obj之上,top layer主要用来放置弹出窗口;

    system layer位于top layer之上;system layer只能放置系统层控件,比如鼠标等;

/**    //lv_disp.h
 * Get the top layer  of the default display
 * @return pointer to the top layer
 */
static inline lv_obj_t *lv_layer_top(void)
{
    return lv_disp_get_layer_top(lv_disp_get_default());
}
//example:
lv_obj_t *bg = lv_layer_top();
lv_obj_set_style_bg_color(bg, lv_color_hex(0x6f8af6), 0);
/**    //lv_disp.h 
 * Get the active screen of the default display
 * @return  pointer to the sys layer
 */
static inline lv_obj_t *lv_layer_sys(void)
{
    return lv_disp_get_layer_sys(lv_disp_get_default());
}
//eg:
perf_label = lv_label_create(lv_layer_sys());
lv_obj_set_style_bg_opa(perf_label, LV_OPA_50, 0);

  2.2 动画加载屏幕

typedef enum {
    LV_SCR_LOAD_ANIM_NONE,          //cae无动画,就是直接加载;
    LV_SCR_LOAD_ANIM_OVER_LEFT,     //cae新屏幕以定向覆盖的方式来加载;
    LV_SCR_LOAD_ANIM_OVER_RIGHT,
    LV_SCR_LOAD_ANIM_OVER_TOP,
    LV_SCR_LOAD_ANIM_OVER_BOTTOM,
    LV_SCR_LOAD_ANIM_MOVE_LEFT,     //cae新旧屏幕一起定向加载;
    LV_SCR_LOAD_ANIM_MOVE_RIGHT,
    LV_SCR_LOAD_ANIM_MOVE_TOP,
    LV_SCR_LOAD_ANIM_MOVE_BOTTOM,
    LV_SCR_LOAD_ANIM_FADE_IN,       //cae在旧屏幕上淡入新屏幕;
    LV_SCR_LOAD_ANIM_FADE_ON = LV_SCR_LOAD_ANIM_FADE_IN, /*For backward compatibility*/
    LV_SCR_LOAD_ANIM_FADE_OUT,
    LV_SCR_LOAD_ANIM_OUT_LEFT,      //cae以旧屏幕定向滑出的方式来加载;
    LV_SCR_LOAD_ANIM_OUT_RIGHT,
    LV_SCR_LOAD_ANIM_OUT_TOP,
    LV_SCR_LOAD_ANIM_OUT_BOTTOM,
} lv_scr_load_anim_t;
/**    //lv_disp.h 以动画方式加载屏幕,本质还是屏幕,而不是动画;
 * Switch screen with animation
 * @param scr pointer to the new screen to load
 * @param anim_type type of the animation from `lv_scr_load_anim_t`, e.g. `LV_SCR_LOAD_ANIM_MOVE_LEFT`
 * @param time time of the animation
 * @param delay delay before the transition
 * @param auto_del true: automatically delete the old screen
 */
void lv_scr_load_anim(lv_obj_t * scr, lv_scr_load_anim_t anim_type, uint32_t time, uint32_t delay, bool auto_del);

  2.3 显示屏幕

    每个screen都是创建在default display上的;default display是最后一个用lv_disp_drv_register( )注册的显示;

    lv_scr_act( ), lv_src_load( ), lv_src_load_anim( )都是在default screen上操作的;

/**    //lv_disp.h  每个屏幕加载之后会在tick时间后更新,也可能是屏幕会在调用lv_scr_act()之后tick时间更新,先放着;
 * Get the active screen of the default display
 * @return pointer to the active screen
 */
static inline lv_obj_t * lv_scr_act(void)
{
    return lv_disp_get_scr_act(lv_disp_get_default());
}

3 parts 

  对象或部件是由一种或多种parts构成的;

  比如basic obj使用main part和scrollbar part,silider使用main part、indicator part、knob part组成;

  如果想设置一个widgets部分parts的样式,那么这个parts用来区分出parts,可不是很方便嘛;

/**    //lv_obj.h
 * The possible parts of widgets.
 * The parts can be considered as the internal building block of the widgets.
 * E.g. slider = background + indicator + knob
 * Not all parts are used by every widget
 */
enum {
    LV_PART_MAIN         = 0x000000,   /**< A background like rectangle*/
    LV_PART_SCROLLBAR    = 0x010000,   /**< The scrollbar(s)*/
    LV_PART_INDICATOR    = 0x020000,   /**< Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox*/
    LV_PART_KNOB         = 0x030000,   /**< Like handle to grab to adjust the value*/
    LV_PART_SELECTED     = 0x040000,   /**< Indicate the currently selected option or section*/
    LV_PART_ITEMS        = 0x050000,   /**< Used if the widget has multiple similar elements (e.g. table cells)*/
    LV_PART_TICKS        = 0x060000,   /**< Ticks on scale e.g. for a chart or meter*/
    LV_PART_CURSOR       = 0x070000,   /**< Mark a specific place e.g. for text area's cursor or on a chart*/

    LV_PART_CUSTOM_FIRST = 0x080000,    /**< Extension point for custom widgets*/

    LV_PART_ANY          = 0x0F0000,    /**< Special value can be used in some functions to target all parts*/
};

typedef uint32_t lv_part_t;

4 状态 states

  对象可以处于以下几种状态的组合,状态通常在用户操作时自动更改,但是也可以代码更改;

  状态的作用是什么呢?在写回调函数的时候,通过设置对哪几个state来响应回调函数;

/**    lv_obj.h
 * Possible states of a widget.
 * OR-ed values are possible
 */
enum {
    LV_STATE_DEFAULT     =  0x0000,	//Normal, released state
    LV_STATE_CHECKED     =  0x0001,	//Toggled or checked state
    LV_STATE_FOCUSED     =  0x0002,	//Focused via keypad or encoder or clicked via touchpad/mouse
    LV_STATE_FOCUS_KEY   =  0x0004,	//Focused via keypad or encoder but not via touchpad/mouse
    LV_STATE_EDITED      =  0x0008,	//Edit by an encoder
    LV_STATE_HOVERED     =  0x0010,	//Hovered by mouse (not supported now)
    LV_STATE_PRESSED     =  0x0020,	//Being pressed
    LV_STATE_SCROLLED    =  0x0040,	//Being scrolled
    LV_STATE_DISABLED    =  0x0080,	//Disabled state

    LV_STATE_USER_1      =  0x1000,
    LV_STATE_USER_2      =  0x2000,
    LV_STATE_USER_3      =  0x4000,
    LV_STATE_USER_4      =  0x8000,

    LV_STATE_ANY = 0xFFFF,    /**< Special value can be used in some functions to target all states*/
};

typedef uint16_t lv_state_t;
/**    //lv_obj.h
 * Add one or more states to the object. The other state bits will remain unchanged.
 * If specified in the styles, transition animation will be started from the previous state to the current.
 * @param obj       pointer to an object
 * @param state     the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED`
 */
void lv_obj_add_state(lv_obj_t *obj, lv_state_t state);

/**
 * Remove one or more states to the object. The other state bits will remain unchanged.
 * If specified in the styles, transition animation will be started from the previous state to the current.
 * @param obj       pointer to an object
 * @param state     the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED`
 */
void lv_obj_clear_state(lv_obj_t *obj, lv_state_t state);

5 坐标 coordinates

  坐标方向:以父类左上角的坐标为原点,水平方向以x轴正方向为lvgl_obj正方向,垂直方向以y轴负方向为lvgl_obj正方向;

  坐标单位:数值的单位都是像素点 pixels;

  坐标存储:lvgl的坐标信息是存储在styles中的;所以可以单独设置坐标信息,也可以使用style对其进行设置;

  5.1 位置 positions

    5.1.1 位置 position

//lv_obj_pos.h
void lv_obj_set_pos(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y);
void lv_obj_set_x(struct _lv_obj_t * obj, lv_coord_t x);
void lv_obj_set_y(struct _lv_obj_t * obj, lv_coord_t y);
void lv_obj_refr_pos(struct _lv_obj_t * obj);    //用法保持怀疑,在tick范围内刷新一遍的话应该不调用也行;

    5.1.2 对齐 align

//lv_area.h 
//child_obj向parent_obj对齐,使用LV_ALIGN_XX,在parent_obj内对齐,以child_obj顶点作为偏移坐标原点;
//                           使用LV_ALIGN_OUT_XX,对齐无效,坐标原点始终是父对象坐标原点;所以不要这么用;
//align_obj向base_obj对齐,  使用LV_ALIGN_OUT_XX,偏移坐标原点为对齐后align_obj原点;
enum _lv_align_t {
    LV_ALIGN_DEFAULT = 0,
    LV_ALIGN_TOP_LEFT,
    LV_ALIGN_TOP_MID,
    LV_ALIGN_TOP_RIGHT,
    LV_ALIGN_BOTTOM_LEFT,
    LV_ALIGN_BOTTOM_MID,
    LV_ALIGN_BOTTOM_RIGHT,
    LV_ALIGN_LEFT_MID,
    LV_ALIGN_RIGHT_MID,
    LV_ALIGN_CENTER,

    LV_ALIGN_OUT_TOP_LEFT,
    LV_ALIGN_OUT_TOP_MID,
    LV_ALIGN_OUT_TOP_RIGHT,
    LV_ALIGN_OUT_BOTTOM_LEFT,
    LV_ALIGN_OUT_BOTTOM_MID,
    LV_ALIGN_OUT_BOTTOM_RIGHT,
    LV_ALIGN_OUT_LEFT_TOP,
    LV_ALIGN_OUT_LEFT_MID,
    LV_ALIGN_OUT_LEFT_BOTTOM,
    LV_ALIGN_OUT_RIGHT_TOP,
    LV_ALIGN_OUT_RIGHT_MID,
    LV_ALIGN_OUT_RIGHT_BOTTOM,
};

#ifdef DOXYGEN
typedef _lv_align_t lv_align_t;
#else
typedef uint8_t lv_align_t;
#endif /*DOXYGEN*/
//lv_obj_pos.h  
//obj向parent对齐,所以不是设计用来配置LV_ALIGN_OUT_XX的;
void lv_obj_align(lv_obj_t * obj, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs);
void lv_obj_set_align(lv_obj_t * obj, lv_align_t align);

//obj向base对齐,对齐之后以obj顶点作为坐标原点
//LV_ALIGN_OUT_XX:obj在base_obj外对齐;
//LV_ALIGN_XX:     obj在base_obj内对齐;
void lv_obj_align_to(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs)

  5.2 尺寸 size

     

//lv_obj_pos.h
void lv_obj_set_size(struct _lv_obj_t * obj, lv_coord_t w, lv_coord_t h);
void lv_obj_set_width(struct _lv_obj_t * obj, lv_coord_t w);    //The actual width: padding left + w + padding right
void lv_obj_set_height(struct _lv_obj_t * obj, lv_coord_t h);   //The actual width: padding top + h + padding bottom
bool lv_obj_refr_size(struct _lv_obj_t * obj);

/**
 * Get the width reduced by the left and right padding and the border width.
 * @param obj       pointer to an object
 * @note            The position of the object is recalculated only on the next redraw. To force coordinate recalculation
 *                  call `lv_obj_update_layout(obj)`.
 * @return          the width which still fits into its parent without causing overflow (making the parent scrollable)
 */
lv_coord_t lv_obj_get_content_width(const struct _lv_obj_t * obj);

/**
 * Get the height reduced by the top and bottom padding and the border width.
 * @param obj       pointer to an object
 * @note            The position of the object is recalculated only on the next redraw. To force coordinate recalculation
 *                  call `lv_obj_update_layout(obj)`.
 * @return          the height which still fits into the parent without causing overflow (making the parent scrollable)
 */
lv_coord_t lv_obj_get_content_height(const struct _lv_obj_t * obj);

  5.3 布局 layouts

    用来更新当前对象子类的position和size,和flexbox、grid部件一起使用,对布局进行实时更新么?先放着;

//lv_obj_pos.h   layout函数并不多,先放着;
extern uint16_t LV_LAYOUT_GRID;        //lv_grid.h
extern uint16_t LV_LAYOUT_FLEX;        //lv_flex.h
void lv_obj_set_layout(struct _lv_obj_t * obj, uint32_t layout);

   5.3.1 flags

      用来配置子类对象 如何响应他的父类对象的layout局部;所以这个flag是layout给子类对象使用的;

//lv_obj.h

/**
 * On/Off features controlling the object's behavior.
 * OR-ed values are possible
 */
enum {
    LV_OBJ_FLAG_HIDDEN          = (1L << 0),  /**< Make the object hidden. (Like it wasn't there at all)*/
    LV_OBJ_FLAG_CLICKABLE       = (1L << 1),  /**< Make the object clickable by the input devices*/
    LV_OBJ_FLAG_CLICK_FOCUSABLE = (1L << 2),  /**< Add focused state to the object when clicked*/
    LV_OBJ_FLAG_CHECKABLE       = (1L << 3),  /**< Toggle checked state when the object is clicked*/
    LV_OBJ_FLAG_SCROLLABLE      = (1L << 4),  /**< Make the object scrollable*/
    LV_OBJ_FLAG_SCROLL_ELASTIC  = (1L << 5),  /**< Allow scrolling inside but with slower speed*/
    LV_OBJ_FLAG_SCROLL_MOMENTUM = (1L << 6),  /**< Make the object scroll further when "thrown"*/
    LV_OBJ_FLAG_SCROLL_ONE      = (1L << 7),  /**< Allow scrolling only one snappable children*/
    LV_OBJ_FLAG_SCROLL_CHAIN_HOR = (1L << 8), /**< Allow propagating the horizontal scroll to a parent*/
    LV_OBJ_FLAG_SCROLL_CHAIN_VER = (1L << 9), /**< Allow propagating the vertical scroll to a parent*/
    LV_OBJ_FLAG_SCROLL_CHAIN     = (LV_OBJ_FLAG_SCROLL_CHAIN_HOR | LV_OBJ_FLAG_SCROLL_CHAIN_VER),
    LV_OBJ_FLAG_SCROLL_ON_FOCUS = (1L << 10),  /**< Automatically scroll object to make it visible when focused*/
    LV_OBJ_FLAG_SCROLL_WITH_ARROW  = (1L << 11), /**< Allow scrolling the focused object with arrow keys*/
    LV_OBJ_FLAG_SNAPPABLE       = (1L << 12), /**< If scroll snap is enabled on the parent it can snap to this object*/
    LV_OBJ_FLAG_PRESS_LOCK      = (1L << 13), /**< Keep the object pressed even if the press slid from the object*/
    LV_OBJ_FLAG_EVENT_BUBBLE    = (1L << 14), /**< Propagate the events to the parent too*/
    LV_OBJ_FLAG_GESTURE_BUBBLE  = (1L << 15), /**< Propagate the gestures to the parent*/
    LV_OBJ_FLAG_ADV_HITTEST     = (1L << 16), /**< Allow performing more accurate hit (click) test. E.g. consider rounded corners.*/
    LV_OBJ_FLAG_IGNORE_LAYOUT   = (1L << 17), /**< Make the object ignored by layouts,so obj can be set as usual*/
    LV_OBJ_FLAG_FLOATING        = (1L << 18), /**< Do not scroll the object when the parent scrolls and ignore layout,这个等于上一行那个*/
    LV_OBJ_FLAG_OVERFLOW_VISIBLE = (1L << 19), /**< Do not clip the children's content to the parent's boundary*/

    LV_OBJ_FLAG_LAYOUT_1        = (1L << 23), /**< Custom flag, free to use by layouts*/
    LV_OBJ_FLAG_LAYOUT_2        = (1L << 24), /**< Custom flag, free to use by layouts*/

    LV_OBJ_FLAG_WIDGET_1        = (1L << 25), /**< Custom flag, free to use by widget*/
    LV_OBJ_FLAG_WIDGET_2        = (1L << 26), /**< Custom flag, free to use by widget*/
    LV_OBJ_FLAG_USER_1          = (1L << 27), /**< Custom flag, free to use by user*/
    LV_OBJ_FLAG_USER_2          = (1L << 28), /**< Custom flag, free to use by user*/
    LV_OBJ_FLAG_USER_3          = (1L << 29), /**< Custom flag, free to use by user*/
    LV_OBJ_FLAG_USER_4          = (1L << 30), /**< Custom flag, free to use by user*/

};
typedef uint32_t lv_obj_flag_t;

/**
 * Set one or more flags
 * @param obj   pointer to an object
 * @param f     R-ed values from `lv_obj_flag_t` to set.
 */
void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f);

/**
 * Clear one or more flags
 * @param obj   pointer to an object
 * @param f     OR-ed values from `lv_obj_flag_t` to set.
 */
void lv_obj_clear_flag(lv_obj_t * obj, lv_obj_flag_t f);

6 小结

  对象obj,以及对象一些基本的简单属性的概括;