README.md
1<h1 align="center"> LittlevGL - Open-source Embedded GUI Library</h1>
2<p align="center">
3<a href="https://github.com/littlevgl/lvgl/blob/master/LICENCE.txt"><img src="https://img.shields.io/badge/licence-MIT-blue.svg"></a>
4<a href="https://github.com/littlevgl/lvgl/releases/tag/v6.0"><img src="https://img.shields.io/badge/version-6.0-blue.svg"></a>
5</p>
6
7<h2 align="center">Shape the future of LittlevGL</h2>
8
9<p align="center">
10<a href="https://www.esurveycreator.com/s/littlevgl-2019"><img src="https://littlevgl.com/external/survey.png"></a>
11</p>
12
13<p align="center">
14It takes only 5 minutes to tell some information about how you use LittlevGL, what you like about it, what should be improved and the future directions you find reasonable.
15</p>
16
17---
18
19<p align="center">
20<img src="https://littlevgl.com/github/cover_ori_reduced_2.gif">
21</p>
22
23<p align="center">
24LittlevGL provides everything you need to create a Graphical User Interface (GUI) on embedded systems with easy-to-use graphical elements, beautiful visual effects and low memory footprint.
25</p>
26
27<h4 align="center">
28<a href="https://littlevgl.com">Website </a> ·
29<a href="https://littlevgl.com/live-demo">Live demo</a> ·
30<a href="https://docs.littlevgl.com/en/html/get-started/pc-simulator.html">Simulator</a> ·
31<a href="https://forum.littlevgl.com">Forum</a> ·
32<a href="https://docs.littlevgl.com/">Docs</a> ·
33<a href="https://blog.littlevgl.com/">Blog</a>
34</h4>
35
36---
37
38- [Features](#features)
39- [Supported devices](#supported-devices)
40- [Quick start in a simulator](#quick-start-in-a-simulator)
41- [Add LittlevGL to your project](#add-littlevgl-to-your-project)
42- [Learn the basics](#learn-the-basics)
43- [Examples](#examples)
44- [Contributing](#contributing)
45- [Donate](#donate)
46
47
48## Features
49* **Powerful building blocks** buttons, charts, lists, sliders, images, etc.
50* **Advanced graphics** with animations, anti-aliasing, opacity, smooth scrolling
51* **Simultaneously use various input devices** touchscreen, mouse, keyboard, encoder, buttons, etc.
52* **Simultaneously use multiple displays** i.e. monochrome and color display
53* **Multi-language support** with UTF-8 encoding
54* **Fully customizable** graphical elements
55* **Hardware independent** to use with any microcontroller or display
56* **Scalable** to operate with little memory (64 kB Flash, 10 kB RAM)
57* **OS, External memory and GPU** supported but not required
58* **Single frame buffer** operation even with advances graphical effects
59* **Written in C** for maximal compatibility
60* **Micropython Binding** exposes [LittlevGL API in Micropython](https://blog.littlevgl.com/2019-02-20/micropython-bindings)
61* **Simulator** to develop on PC without embedded hardware
62* **Tutorials, examples, themes** for rapid development
63* **Documentation** and API references
64
65## Supported devices
66Basically, every modern controller - which is able to drive a display - is suitable to run LittlevGL. The minimal requirements:
67- 16, 32 or 64 bit microcontroller or processor
68- > 16 MHz clock speed is recommended
69- Flash/ROM: > 64 kB for the very essential components (> 180 kB is recommended)
70- RAM:
71 - Static RAM usage: ~8..16 kB depending on the used features and objects types
72 - Stack: > 2kB (> 4 kB is recommended)
73 - Dynamic data (heap): > 4 KB (> 16 kB is recommended if using several objects).
74 Set by `LV_MEM_SIZE` in *lv_conf.h*.
75 - Display buffer: > *"Horizontal resolution"* pixels (> 10 × *"Horizontal resolution"* is recommended)
76- C99 or newer compiler
77
78*Note that the memory usage might vary depending on the architecture, compiler and build options.*
79
80Just to mention some **platforms**:
81- STM32F1, STM32F3, [STM32F4](https://blog.littlevgl.com/2017-07-15/stm32f429_disco_port), [STM32F7](https://github.com/littlevgl/stm32f746_disco_no_os_sw4stm32)
82- Microchip dsPIC33, PIC24, PIC32MX, PIC32MZ
83- NXP Kinetis, LPC, iMX
84- [Linux frame buffer](https://blog.littlevgl.com/2018-01-03/linux_fb) (/dev/fb)
85- [Raspberry PI](http://www.vk3erw.com/index.php/16-software/63-raspberry-pi-official-7-touchscreen-and-littlevgl)
86- [Espressif ESP32](https://github.com/littlevgl/esp32_ili9431)
87- Nordic nrf52
88- Quectell M66
89
90## Quick start in a simulator
91The easiest way to get started with LittlevGL is to run it in a simulator on your PC without any embedded hardware.
92
93Choose a project with your favourite IDE:
94
95| Eclipse | CodeBlocks | Visual Studio | PlatformIO | Qt Creator |
96|-------------|-------------|---------------|-----------|------------|
97| [](https://github.com/littlevgl/pc_simulator_sdl_eclipse) | [](https://github.com/littlevgl/pc_simulator_win_codeblocks) | [](https://github.com/littlevgl/visual_studio_2017_sdl_x64) | [](https://github.com/littlevgl/pc_simulator_sdl_platformio) | [](https://blog.littlevgl.com/2019-01-03/qt-creator) |
98| Cross-platform<br>with SDL | Native Windows | Cross-platform<br>with SDL | Cross-platform<br>with SDL | Cross-platform<br>with SDL |
99
100
101## Add LittlevGL to your project
102
103The steps below show how to setup LittlevGL on an embedded system with a display and a touchpad.
104You can use the [Simulators](https://docs.littlevgl.com/en/html/get-started/pc-simulator) to get ready to use projects which can be run on your PC.
105
1061. [Download](https://littlevgl.com/download) or [Clone](https://github.com/littlevgl/lvgl) the library
1072. Copy the `lvgl` folder into your project
1083. Copy `lvgl/lv_conf_templ.h` as `lv_conf.h` next to the `lvgl` folder and set at least `LV_HOR_RES_MAX`, `LV_VER_RES_MAX` and `LV_COLOR_DEPTH`.
1094. Include `lvgl/lvgl.h` where you need to use LittlevGL related functions.
1105. Call `lv_tick_inc(x)` every `x` milliseconds **in a Timer or Task** (`x` should be between 1 and 10). It is required for the internal timing of LittlevGL.
1116. Call `lv_init()`
1127. Create a display buffer for LittlevGL
113```c
114static lv_disp_buf_t disp_buf;
115static lv_color_t buf[LV_HOR_RES_MAX * 10]; /*Declare a buffer for 10 lines*/
116lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
117```
1188. Implement and register a function which can **copy a pixel array** to an area of your display:
119```c
120lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
121lv_disp_drv_init(&disp_drv); /*Basic initialization*/
122disp_drv.flush_cb = my_disp_flush; /*Set your driver function*/
123disp_drv.buffer = &disp_buf; /*Assign the buffer to the display*/
124lv_disp_drv_register(&disp_drv); /*Finally register the driver*/
125
126void my_disp_flush(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p)
127{
128 int32_t x, y;
129 for(y = area->y1; y <= area->y2; y++) {
130 for(x = area->x1; x <= area->x2; x++) {
131 set_pixel(x, y, *color_p); /* Put a pixel to the display.*/
132 color_p++;
133 }
134 }
135
136 lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/
137}
138
139```
1409. Implement and register a function which can **read an input device**. E.g. for a touch pad:
141```c
142lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/
143indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
144indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
145lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
146
147bool my_touchpad_read(lv_indev_t * indev, lv_indev_data_t * data)
148{
149 static lv_coord_t last_x = 0;
150 static lv_coord_t last_y = 0;
151
152 /*Save the state and save the pressed coordinate*/
153 data->state = touchpad_is_pressed() ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
154 if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
155
156 /*Set the coordinates (if released use the last pressed coordinates)*/
157 data->point.x = last_x;
158 data->point.y = last_y;
159
160 return false; /*Return `false` because we are not buffering and no more data to read*/
161}
162```
16310. Call `lv_task_handler()` periodically every few milliseconds in the main `while(1)` loop, in Timer interrupt or in an Operation system task.
164It will redraw the screen if required, handle input devices etc.
165
166
167## Learn the basics
168
169### Objects (Widgets)
170
171The graphical elements like Buttons, Labels, Sliders, Charts etc are called objects in LittelvGL. Go to [Object types](https://docs.littlevgl.com/en/html/object-types/index) to see the full list of available types.
172
173Every object has a parent object. The child object moves with the parent and if you delete the parent the children will be deleted too. Children can be visible only on their parent.
174
175The *screen* are the "root" parents. To get the current screen call `lv_scr_act()`.
176
177You can create a new object with `lv_<type>_create(parent, obj_to_copy)`. It will return an `lv_obj_t *` variable which should be used as a reference to the object to set its parameters.
178The first parameter is the desired *parent*, te second parameters can be an object to copy (`NULL` is unused).
179For example:
180```c
181lv_obj_t * slider1 = lv_slider_create(lv_scr_act(), NULL);
182```
183
184To set some basic attribute `lv_obj_set_<paramters_name>(obj, <value>)` function can be used. For example:
185```c
186lv_obj_set_x(btn1, 30);
187lv_obj_set_y(btn1, 10);
188lv_obj_set_size(btn1, 200, 50);
189```
190
191The objects has type specific parameters too which can be set by `lv_<type>_set_<paramters_name>(obj, <value>)` functions. For example:
192```c
193lv_slider_set_value(slider1, 70, LV_ANIM_ON);
194```
195
196To see the full API visit the documentation of the object types or the related header file (e.g. `lvgl/src/lv_objx/lv_slider.h`).
197
198### Styles
199Styles can be assigned to the objects to changed their appearance. A style describes the appearance of rectangle-like objects (like a button or slider), texts, images and lines at once.
200
201You can create a new style like this:
202```c
203static lv_style_t style1; /*Declare a new style. Should be `static`*/
204lv_style_copy(&style1, &lv_style_plain); /*Copy a buil-in style*/
205style1.body.main_color = LV_COLOR_RED; /*Main color*/
206style1.body.grad_color = lv_color_hex(0xffd83c) /*Gradient color (orange)*/
207style1.body.radius = 3;
208style1.text.color = lv_color_hex3(0x0F0) /*Label color (green)*/
209style1.text.font = &lv_font_dejavu_22; /*Change font*/
210...
211```
212
213To set a new style for an object use the `lv_<type>set_style(obj, LV_<TYPE>_STYLE_<NAME>, &my_style)` functions. For example:
214```c
215lv_slider_set_style(slider1, LV_SLIDER_STYLE_BG, &slider_bg_style);
216lv_slider_set_style(slider1, LV_SLIDER_STYLE_INDIC, &slider_indic_style);
217lv_slider_set_style(slider1, LV_SLIDER_STYLE_KNOB, &slider_knob_style);
218```
219
220If an object's style is `NULL` then it will inherit its parent's style. For example, the labels' style are `NULL` by default. If you place them on a button then they will use the `style.text` properties from the button's style.
221
222Learn more in [Style overview](https://docs.littlevgl.com/en/html/overview/style) section.
223
224### Events
225Events are used to inform the user if something has happened with an object. You can assign a callback to an object which will be called if the object is clicked, released, dragged, being deleted etc. It should look like this:
226
227```c
228lv_obj_set_event_cb(btn, btn_event_cb); /*Assign a callback to the button*/
229
230...
231
232void btn_event_cb(lv_obj_t * btn, lv_event_t event)
233{
234 if(event == LV_EVENT_CLICKED) {
235 printf("Clicked\n");
236 }
237}
238```
239
240Learn more about the events in the [Event overview](https://docs.littlevgl.com/en/html/overview/event) section.
241
242
243## Examples
244
245### Button with label
246```c
247lv_obj_t * btn = lv_btn_create(lv_scr_act(), NULL); /*Add a button the current screen*/
248lv_obj_set_pos(btn, 10, 10); /*Set its position*/
249lv_obj_set_size(btn, 100, 50); /*Set its size*/
250lv_obj_set_event_cb(btn, btn_event_cb); /*Assign a callback to the button*/
251
252lv_obj_t * label = lv_label_create(btn, NULL); /*Add a label to the button*/
253lv_label_set_text(label, "Button"); /*Set the labels text*/
254
255...
256
257void btn_event_cb(lv_obj_t * btn, lv_event_t event)
258{
259 if(event == LV_EVENT_CLICKED) {
260 printf("Clicked\n");
261 }
262}
263```
264
265
266### Button with styles
267Add styles to the previously button from the previous example
268```c
269static lv_style_t style_btn_rel; /*A variable to store the released style*/
270lv_style_copy(&style_btn_rel, &lv_style_plain); /*Initialize from a built-in style*/
271style_btn_rel.body.border.color = lv_color_hex3(0x269);
272style_btn_rel.body.border.width = 1;
273style_btn_rel.body.main_color = lv_color_hex3(0xADF);
274style_btn_rel.body.grad_color = lv_color_hex3(0x46B);
275style_btn_rel.body.shadow.width = 4;
276style_btn_rel.body.shadow.type = LV_SHADOW_BOTTOM;
277style_btn_rel.body.radius = LV_RADIUS_CIRCLE;
278style_btn_rel.text.color = lv_color_hex3(0xDEF);
279
280static lv_style_t style_btn_pr; /*A variable to store the pressed style*/
281lv_style_copy(&style_btn_pr, &style_btn_rel); /*Initialize from the released style*/
282style_btn_pr.body.border.color = lv_color_hex3(0x46B);
283style_btn_pr.body.main_color = lv_color_hex3(0x8BD);
284style_btn_pr.body.grad_color = lv_color_hex3(0x24A);
285style_btn_pr.body.shadow.width = 2;
286style_btn_pr.text.color = lv_color_hex3(0xBCD);
287
288lv_btn_set_style(btn, LV_BTN_STYLE_REL, &style_btn_rel); /*Set the button's released style*/
289lv_btn_set_style(btn, LV_BTN_STYLE_PR, &style_btn_pr); /*Set the button's pressed style*/
290```
291
292
293
294### Slider and object alignment
295```c
296lv_obj_t * label;
297
298...
299
300/* Create a slider in the center of the display */
301lv_obj_t * slider = lv_slider_create(lv_scr_act(), NULL);
302lv_obj_set_width(slider, 200); /*Set the width*/
303lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0); /*Align to the center of the parent (screen)*/
304lv_obj_set_event_cb(slider, slider_event_cb); /*Assign an event function*/
305
306/* Create a label below the slider */
307label = lv_label_create(lv_scr_act(), NULL);
308lv_label_set_text(label, "0");
309lv_obj_set_auto_realign(slider, true);
310lv_obj_align(label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
311
312...
313
314void slider_event_cb(lv_obj_t * slider, lv_event_t event)
315{
316 if(event == LV_EVENT_VALUE_CHANGED) {
317 static char buf[4]; /* max 3 bytes for number plus 1 null terminating byte */
318 snprintf(buf, 4, "%u", lv_slider_get_value(slider));
319 lv_label_set_text(slider_label, buf); /*Refresh the text*/
320 }
321}
322```
323
324
325
326### List and themes
327```c
328/*Texts of the list elements*/
329const char * txts[] = {"First", "Second", "Third", "Forth", "Fifth", "Sixth", NULL};
330
331/* Initialize and set a theme. `LV_THEME_NIGHT` needs to enabled in lv_conf.h. */
332lv_theme_t * th = lv_theme_night_init(20, NULL);
333lv_theme_set_current(th);
334
335/*Create a list*/
336lv_obj_t* list = lv_list_create(lv_scr_act(), NULL);
337lv_obj_set_size(list, 120, 180);
338lv_obj_set_pos(list, 10, 10);
339
340/*Add buttons*/
341uint8_t i;
342for(i = 0; txts[i]; i++) {
343 lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_FILE, txts[i]);
344 lv_obj_set_event_cb(btn, list_event); /*Assign event function*/
345 lv_btn_set_toggle(btn, true); /*Enable on/off states*/
346}
347
348/* Initialize and set an other theme. `LV_THEME_MATERIAL` needs to enabled in lv_conf.h.
349 * If `LV_TEHE_LIVE_UPDATE 1` then the previous list's style will be updated too.*/
350th = lv_theme_material_init(210, NULL);
351lv_theme_set_current(th);
352
353/*Create an other list*/
354list = lv_list_create(lv_scr_act(), NULL);
355lv_obj_set_size(list, 120, 180);
356lv_obj_set_pos(list, 150, 10);
357
358/*Add buttons with the same texts*/
359for(i = 0; txts[i]; i++) {
360 lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_FILE, txts[i]);
361 lv_obj_set_event_cb(btn, list_event);
362 lv_btn_set_toggle(btn, true);
363}
364
365...
366
367static void list_event(lv_obj_t * btn, lv_event_t e)
368{
369 if(e == LV_EVENT_CLICKED) {
370 printf("%s\n", lv_list_get_btn_text(btn));
371 }
372
373}
374```
375
376
377### Use LittlevGL from Micropython
378Learn more about [Micropython](https://docs.littlevgl.com/en/html/get-started/micropython).
379```python
380# Create a Button and a Label
381scr = lv.obj()
382btn = lv.btn(scr)
383btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
384label = lv.label(btn)
385label.set_text("Button")
386
387# Load the screen
388lv.scr_load(scr)
389```
390
391## Contributing
392To ask questions please use the [Forum](https://forum.littlevgl.com).
393For development-related things (bug reports, feature suggestions) use [GitHub's Issue tracker](https://github.com/littlevgl/lvgl/issues).
394
395If you are interested in contributing to LittlevGL you can
396- **Help others** in the [Forum](https://forum.littlevgl.com).
397- **Inspire people** by speaking about your project in [My project](https://forum.littlevgl.com/c/my-projects) category in the Forum or add it to the [References](https://blog.littlevgl.com/2018-12-26/references) post
398- **Improve and/or translate the documentation.** Go to the [Documentation](https://github.com/littlevgl/docs) repository to learn more
399- **Write a blog post** about your experiences. See how to do it in the [Blog](https://github.com/littlevgl/blog) repository
400- **Report and/or fix bugs** in [GitHub's issue tracker](https://github.com/littlevgl/lvgl/issues)
401- **Help in the developement**. Check the [Open issues](https://github.com/littlevgl/lvgl/issues) especially the ones with [Help wanted](https://github.com/littlevgl/lvgl/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) label and tell your ideas about a topic or implement a feature.
402
403It should be useful to read the
404- [Contributing guide](https://blog.littlevgl.com/2018-12-06/contributing)
405- [Coding style guide](https://github.com/littlevgl/lvgl/blob/master/docs/CODING_STYLE.md)
406
407## Donate
408If you are pleased with the library, found it useful, or you are happy with the support you got, please help its further development:
409
410[](https://littlevgl.com/donate)
411