一,前言
最近我喜欢上了界面美化。无意中看到基于单片机的GUI引擎littlevgl,这个可能是2020年火起来的,因为正点原子及华为liteos好像都用它做GUI,理解了下做物联网GUI还真的是够用了,比较漂亮,而且API简单,另外界面编辑器也已经到了0.2版本,就说直接在界面编辑器中就可以生成API。但是我学习的重点是了解GUI框架引擎开发的机制,而不是使用它。当然,前提需要会简单的应用。
二,lvgl入门
网上资料很多,官网资料也很好,我学习了下,主要是它支持PC模拟器,这是我最喜欢的了,应用便于调试快速理解代码框架。
关于stm32F4的移植我也思考了下,我买的是F407,网上说移植后界面刷新很卡,要用F429带DMA2D加速模块的,所以先不考虑移植了,主要学习GUI引擎设计思路。
先在PC上codeblocks+SDL2环境上建立了工程,官网教程都看了下。example中的函数都调用看了下,做了一个简单的应用,button按下后arc角度加5。关于界面对象格式用的是默认的,没有调用API进行自定义。
三,lvgl源码分析
之前因为学习过guilite源码。用来做动效主要是surface可以支持2层,这样也可以有popup窗口的支持。那么我看了这些lvgl的GUI都比较漂亮,它的代码量比guilite多很多了。所以界面wigit都已经帮我们做好了,然后我们通过设置style来自定义风格,所以lvgl的源码量比较多就是这个原因,然后它有层的概念吗?可以支持popup窗口吗?我看了它的应用后觉得是可以的。然后开始看源码?为什么说是可以的。
lvgl的设计思路也是事件扫描,扫描到事件后,开始reflush。而它里面的所谓surface的概念应该是lv_disp_t结构体中top_layer和sys_layer吧。另外,它有obj的概念,每个ogj可以关联为另外一个的父类。
disp_flush回调函数,//把指定区域的显示缓冲区内容写入到屏幕。就可以写到SDL或者stm32的LCD中。
lv_refr_area_part里面是绘图,lv_obj_event_base中的 base->event_cb(obj, e);就是lv_obj_event_cb函数,lv_obj_event_cb传入参数LV_EVENT_DRAW_MAIN则调用函数lv_obj_draw函数,包括lv_draw_rect,最后调用_lv_blend_fill->fill_normal->lv_color_fill里面填充区域。
/*Create a temp. disp_buf which always point to the first pixel of the destination area*/
lv_color_t * disp_buf_first = disp_buf + disp_w * draw_area->y1 + draw_area->x1;
/*Software rendering*/
for(y = 0; y < draw_area_h; y++) {
lv_color_fill(disp_buf_first, color, draw_area_w);
disp_buf_first += disp_w;
}
而关于obj的绘制我理解他是一个个绘制的,但是关于popup后窗口还原到底层视图,我还没有仔细看代码。
四,小结
在学习lvgl的过程中,网上看到了还有很多优秀的适合于单片机的GUI引擎,那么我为什么要选择看基于单片机的GUI引擎呢!原因就是它的代码一定比较简单,麻雀虽小五脏俱全,对应我要学习设计思路是再好不过的选择了。可以总结为我想先学习小而精的代码。