LVGL-V8框架简析之Style
LVGL自V7~V8众多版本中,变化最大之一的就是Style了,LVGL之所以支持多样式的控件风格设计就是得益于Style的优秀设计。LVGL的V6及以前版本没怎么使用过,所以还是从V7开始做了解。
对于V7,Style的使用方式多是直接调用Style设计函数针对某一个控件进行样式(风格)的绑定,例如设置控件背景透明度lv_obj_set_style_local_bg_opa,确实这类命名方式很方便对控件做样式设计,逐个绑定就是了,并且只要是控件都是obj类型的没有区别,当然也有一些问题,那就是当控件数量多的时候,还设置这么多样式就增加了很多代码量。
不过V7也支持定义样式变量,这样就可以一种样式给很多个控件做装饰了,例如调用lv_style_init初始化style_btn变量并给它设定样式,这样一排按钮都可以调用lv_obj_add_style使用style_btn的样式了。
然后按键可以定义成数组,一个循环就可以全部设定样式,即使绝对坐标不一样,乘个控件宽度加间隙也能一块设置了,按钮文本不一样?字符串数组了解一下,还是一个循环的事情,非常高效便捷,所以一开始我就不理解为什么一群人离开设计器跟不能活一样,LVGL都这么灵活了,还用得到设计器?
V7中为了支持控件众多的样式设计,写了很多很多很多很多的style设计函数,甚至用到了当时最难理解的宏定义_LV_OBJ_STYLE_SET_GET_DECLARE来定义函数,好处就是减少了代码量,毕竟复制粘贴改名称多了也会烦。
但是真正用到了V8的release版本,事情开始不对劲,LVGL的Style愈发难以看懂了,结构体复杂程度让我怀疑小单片机根本跑不动。
V8的Style最最最底层的结构体成员之一是lv_style_prop_t,翻译为样式所有物,即列举了所有可设置的样式列表,例如尺寸等第0组样式。
又或是背景等的第2组样式,包含背景色、透明度、渐变色、渐变色方向、背景图、背景图透明度、背景图重绘色等等样式。
其他还有边框、阴影、字体、线条等等就不列举了。另外一个是值成员,它是一个联合体。
值成员用于表示样式的具体值,例如设置控件线条宽度,可以是int32_t类型的5,表示5个像素线宽,例如设置标签控件label的字体是16号字体,那么这个值就可以使const coid *指针类型的,指向一个字库,例如设置按键控件btn的背景色,那么就可以是lv_color_t类型的LV_COLOR_RED,不过从V8开始颜色就没有预定义了,只有lv_color_hex自己现编颜色。
样式所有物和值共同组成lv_style_const_prop_t结构体。lv_style_const_prop_t指针变量或者uint8_t *指针或者直接样式值lv_style_value_t类型共同组成v_p联合体。v_p联合体又与prop1、has_group、prop_cnt变量共同组成最终的样式结构体,即lv_style_t,其中prop用于内部的标记用户一般不操作、has_group用于记录组数,当调用V8的style样式设置函数如lv_style_set_bg_color就会依次调用lv_style_set_prop->lv_style_set_prop_internal,最后通过_lv_style_get_prop_group计算组数并赋值has_group例如设置长度就和设置宽度是一组,设置背景色就和设置背景透明度一组,LVGL预留了7组每组16个样式,prop_cnt用于记录设置了多少个样式,并且通过枚举可以避免重复设置样式的重复内存占用。
同样的,为了设置这么多的样式就需要定义这么多函数,V8取消了V7中的宏替代定义,实打实的写了近100个函数,其实也就是对lv_obj_set_local_style_prop函数的封装,把函数名对应到了枚举的样式类型。
同样的,也可以用lv_style_init初始化一个style,然后lv_style_set_prop添加style,再lv_obj_add_style给控件添加style。