summaryrefslogtreecommitdiff
path: root/lib/lvgl/examples/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'lib/lvgl/examples/widgets')
m---------lib/lvgl0
-rw-r--r--lib/lvgl/examples/widgets/animimg/index.rst7
-rw-r--r--lib/lvgl/examples/widgets/animimg/lv_example_animimg_1.c23
-rw-r--r--lib/lvgl/examples/widgets/animimg/lv_example_animimg_1.py54
-rw-r--r--lib/lvgl/examples/widgets/arc/index.rst14
-rw-r--r--lib/lvgl/examples/widgets/arc/lv_example_arc_1.c35
-rw-r--r--lib/lvgl/examples/widgets/arc/lv_example_arc_1.py8
-rw-r--r--lib/lvgl/examples/widgets/arc/lv_example_arc_2.c37
-rw-r--r--lib/lvgl/examples/widgets/arc/lv_example_arc_2.py37
-rw-r--r--lib/lvgl/examples/widgets/bar/index.rst36
-rw-r--r--lib/lvgl/examples/widgets/bar/lv_example_bar_1.c12
-rw-r--r--lib/lvgl/examples/widgets/bar/lv_example_bar_1.py5
-rw-r--r--lib/lvgl/examples/widgets/bar/lv_example_bar_2.c34
-rw-r--r--lib/lvgl/examples/widgets/bar/lv_example_bar_2.py27
-rw-r--r--lib/lvgl/examples/widgets/bar/lv_example_bar_3.c40
-rw-r--r--lib/lvgl/examples/widgets/bar/lv_example_bar_3.py32
-rw-r--r--lib/lvgl/examples/widgets/bar/lv_example_bar_4.c27
-rw-r--r--lib/lvgl/examples/widgets/bar/lv_example_bar_4.py45
-rw-r--r--lib/lvgl/examples/widgets/bar/lv_example_bar_5.c32
-rw-r--r--lib/lvgl/examples/widgets/bar/lv_example_bar_5.py22
-rw-r--r--lib/lvgl/examples/widgets/bar/lv_example_bar_6.c69
-rw-r--r--lib/lvgl/examples/widgets/bar/lv_example_bar_6.py54
-rw-r--r--lib/lvgl/examples/widgets/bar/test.py57
-rw-r--r--lib/lvgl/examples/widgets/btn/index.rst20
-rw-r--r--lib/lvgl/examples/widgets/btn/lv_example_btn_1.c38
-rw-r--r--lib/lvgl/examples/widgets/btn/lv_example_btn_1.py32
-rw-r--r--lib/lvgl/examples/widgets/btn/lv_example_btn_2.c65
-rw-r--r--lib/lvgl/examples/widgets/btn/lv_example_btn_2.py60
-rw-r--r--lib/lvgl/examples/widgets/btn/lv_example_btn_3.c45
-rw-r--r--lib/lvgl/examples/widgets/btn/lv_example_btn_3.py38
-rw-r--r--lib/lvgl/examples/widgets/btnmatrix/index.rst22
-rw-r--r--lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_1.c33
-rw-r--r--lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_1.py24
-rw-r--r--lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_2.c78
-rw-r--r--lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_2.py81
-rw-r--r--lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_3.c68
-rw-r--r--lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_3.py64
-rw-r--r--lib/lvgl/examples/widgets/calendar/index.rst7
-rw-r--r--lib/lvgl/examples/widgets/calendar/lv_example_calendar_1.c51
-rw-r--r--lib/lvgl/examples/widgets/calendar/lv_example_calendar_1.py30
-rw-r--r--lib/lvgl/examples/widgets/canvas/index.rst13
-rw-r--r--lib/lvgl/examples/widgets/canvas/lv_example_canvas_1.c53
-rw-r--r--lib/lvgl/examples/widgets/canvas/lv_example_canvas_1.py43
-rw-r--r--lib/lvgl/examples/widgets/canvas/lv_example_canvas_2.c44
-rw-r--r--lib/lvgl/examples/widgets/canvas/lv_example_canvas_2.py43
-rw-r--r--lib/lvgl/examples/widgets/chart/index.rst49
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_1.c44
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_1.py26
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_2.c130
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_2.py76
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_3.c76
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_3.py52
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_4.c86
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_4.py73
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_5.c99
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_5.py89
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_6.c87
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_6.py88
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_7.c66
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_7.py77
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_8.c131
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_8.py124
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_9.c46
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_9.py31
-rw-r--r--lib/lvgl/examples/widgets/checkbox/index.rst12
-rw-r--r--lib/lvgl/examples/widgets/checkbox/lv_example_checkbox_1.c43
-rw-r--r--lib/lvgl/examples/widgets/checkbox/lv_example_checkbox_1.py36
-rw-r--r--lib/lvgl/examples/widgets/checkbox/lv_example_checkbox_2.c86
-rw-r--r--lib/lvgl/examples/widgets/colorwheel/index.rst7
-rw-r--r--lib/lvgl/examples/widgets/colorwheel/lv_example_colorwheel_1.c13
-rw-r--r--lib/lvgl/examples/widgets/colorwheel/lv_example_colorwheel_1.py4
-rw-r--r--lib/lvgl/examples/widgets/dropdown/index.rst20
-rw-r--r--lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_1.c35
-rw-r--r--lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_1.py26
-rw-r--r--lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_2.c39
-rw-r--r--lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_2.py34
-rw-r--r--lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_3.c43
-rw-r--r--lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_3.py53
-rw-r--r--lib/lvgl/examples/widgets/img/index.rst28
-rw-r--r--lib/lvgl/examples/widgets/img/lv_example_img_1.c18
-rw-r--r--lib/lvgl/examples/widgets/img/lv_example_img_1.py32
-rw-r--r--lib/lvgl/examples/widgets/img/lv_example_img_2.c64
-rw-r--r--lib/lvgl/examples/widgets/img/lv_example_img_2.py70
-rw-r--r--lib/lvgl/examples/widgets/img/lv_example_img_3.c43
-rw-r--r--lib/lvgl/examples/widgets/img/lv_example_img_3.py61
-rw-r--r--lib/lvgl/examples/widgets/img/lv_example_img_4.c41
-rw-r--r--lib/lvgl/examples/widgets/img/lv_example_img_4.py51
-rw-r--r--lib/lvgl/examples/widgets/imgbtn/index.rst7
-rw-r--r--lib/lvgl/examples/widgets/imgbtn/lv_example_imgbtn_1.c41
-rw-r--r--lib/lvgl/examples/widgets/imgbtn/lv_example_imgbtn_1.py74
-rw-r--r--lib/lvgl/examples/widgets/keyboard/index.rst7
-rw-r--r--lib/lvgl/examples/widgets/keyboard/lv_example_keyboard_1.c40
-rw-r--r--lib/lvgl/examples/widgets/keyboard/lv_example_keyboard_1.py28
-rw-r--r--lib/lvgl/examples/widgets/label/index.rst31
-rw-r--r--lib/lvgl/examples/widgets/label/lv_example_label_1.c25
-rw-r--r--lib/lvgl/examples/widgets/label/lv_example_label_1.py19
-rw-r--r--lib/lvgl/examples/widgets/label/lv_example_label_2.c36
-rw-r--r--lib/lvgl/examples/widgets/label/lv_example_label_2.py30
-rw-r--r--lib/lvgl/examples/widgets/label/lv_example_label_3.c31
-rw-r--r--lib/lvgl/examples/widgets/label/lv_example_label_3.py36
-rw-r--r--lib/lvgl/examples/widgets/label/lv_example_label_4.c63
-rw-r--r--lib/lvgl/examples/widgets/label/lv_example_label_5.c30
-rw-r--r--lib/lvgl/examples/widgets/label/lv_example_label_5.py10
-rw-r--r--lib/lvgl/examples/widgets/led/index.rst7
-rw-r--r--lib/lvgl/examples/widgets/led/lv_example_led_1.c26
-rw-r--r--lib/lvgl/examples/widgets/led/lv_example_led_1.py20
-rw-r--r--lib/lvgl/examples/widgets/line/index.rst7
-rw-r--r--lib/lvgl/examples/widgets/line/lv_example_line_1.c24
-rw-r--r--lib/lvgl/examples/widgets/line/lv_example_line_1.py20
-rw-r--r--lib/lvgl/examples/widgets/list/index.rst13
-rw-r--r--lib/lvgl/examples/widgets/list/lv_example_list_1.c53
-rw-r--r--lib/lvgl/examples/widgets/list/lv_example_list_1.py40
-rw-r--r--lib/lvgl/examples/widgets/list/lv_example_list_2.c169
-rw-r--r--lib/lvgl/examples/widgets/list/lv_example_list_2.py137
-rwxr-xr-xlib/lvgl/examples/widgets/list/test.py43
-rw-r--r--lib/lvgl/examples/widgets/lv_example_widgets.h148
-rw-r--r--lib/lvgl/examples/widgets/menu/index.rst31
-rw-r--r--lib/lvgl/examples/widgets/menu/lv_example_menu_1.c40
-rw-r--r--lib/lvgl/examples/widgets/menu/lv_example_menu_1.py28
-rw-r--r--lib/lvgl/examples/widgets/menu/lv_example_menu_2.c52
-rw-r--r--lib/lvgl/examples/widgets/menu/lv_example_menu_2.py36
-rw-r--r--lib/lvgl/examples/widgets/menu/lv_example_menu_3.c59
-rw-r--r--lib/lvgl/examples/widgets/menu/lv_example_menu_3.py43
-rw-r--r--lib/lvgl/examples/widgets/menu/lv_example_menu_4.c70
-rw-r--r--lib/lvgl/examples/widgets/menu/lv_example_menu_4.py47
-rw-r--r--lib/lvgl/examples/widgets/menu/lv_example_menu_5.c199
-rw-r--r--lib/lvgl/examples/widgets/meter/index.rst28
-rw-r--r--lib/lvgl/examples/widgets/meter/lv_example_meter_1.c66
-rw-r--r--lib/lvgl/examples/widgets/meter/lv_example_meter_1.py58
-rw-r--r--lib/lvgl/examples/widgets/meter/lv_example_meter_2.c60
-rw-r--r--lib/lvgl/examples/widgets/meter/lv_example_meter_2.py69
-rw-r--r--lib/lvgl/examples/widgets/meter/lv_example_meter_3.c54
-rw-r--r--lib/lvgl/examples/widgets/meter/lv_example_meter_3.py83
-rw-r--r--lib/lvgl/examples/widgets/meter/lv_example_meter_4.c38
-rw-r--r--lib/lvgl/examples/widgets/meter/lv_example_meter_4.py32
-rw-r--r--lib/lvgl/examples/widgets/msgbox/index.rst8
-rw-r--r--lib/lvgl/examples/widgets/msgbox/lv_example_msgbox_1.c19
-rw-r--r--lib/lvgl/examples/widgets/msgbox/lv_example_msgbox_1.py10
-rw-r--r--lib/lvgl/examples/widgets/obj/index.rst13
-rw-r--r--lib/lvgl/examples/widgets/obj/lv_example_obj_1.c22
-rw-r--r--lib/lvgl/examples/widgets/obj/lv_example_obj_1.py14
-rw-r--r--lib/lvgl/examples/widgets/obj/lv_example_obj_2.c35
-rw-r--r--lib/lvgl/examples/widgets/obj/lv_example_obj_2.py25
-rw-r--r--lib/lvgl/examples/widgets/roller/index.rst19
-rw-r--r--lib/lvgl/examples/widgets/roller/lv_example_roller_1.c41
-rw-r--r--lib/lvgl/examples/widgets/roller/lv_example_roller_1.py31
-rw-r--r--lib/lvgl/examples/widgets/roller/lv_example_roller_2.c60
-rw-r--r--lib/lvgl/examples/widgets/roller/lv_example_roller_2.py60
-rw-r--r--lib/lvgl/examples/widgets/roller/lv_example_roller_3.c96
-rw-r--r--lib/lvgl/examples/widgets/roller/lv_example_roller_3.py99
-rw-r--r--lib/lvgl/examples/widgets/slider/index.rst20
-rw-r--r--lib/lvgl/examples/widgets/slider/lv_example_slider_1.c33
-rw-r--r--lib/lvgl/examples/widgets/slider/lv_example_slider_1.py20
-rw-r--r--lib/lvgl/examples/widgets/slider/lv_example_slider_2.c57
-rw-r--r--lib/lvgl/examples/widgets/slider/lv_example_slider_2.py48
-rw-r--r--lib/lvgl/examples/widgets/slider/lv_example_slider_3.c56
-rw-r--r--lib/lvgl/examples/widgets/slider/lv_example_slider_3.py43
-rw-r--r--lib/lvgl/examples/widgets/span/index.rst7
-rw-r--r--lib/lvgl/examples/widgets/span/lv_example_span_1.c58
-rw-r--r--lib/lvgl/examples/widgets/span/lv_example_span_1.py53
-rw-r--r--lib/lvgl/examples/widgets/spinbox/index.rst7
-rw-r--r--lib/lvgl/examples/widgets/spinbox/lv_example_spinbox_1.c48
-rw-r--r--lib/lvgl/examples/widgets/spinbox/lv_example_spinbox_1.py30
-rw-r--r--lib/lvgl/examples/widgets/spinner/index.rst7
-rw-r--r--lib/lvgl/examples/widgets/spinner/lv_example_spinner_1.c12
-rw-r--r--lib/lvgl/examples/widgets/spinner/lv_example_spinner_1.py6
-rw-r--r--lib/lvgl/examples/widgets/switch/index.rst7
-rw-r--r--lib/lvgl/examples/widgets/switch/lv_example_switch_1.c36
-rw-r--r--lib/lvgl/examples/widgets/switch/lv_example_switch_1.py28
-rw-r--r--lib/lvgl/examples/widgets/table/index.rst14
-rw-r--r--lib/lvgl/examples/widgets/table/lv_example_table_1.c65
-rw-r--r--lib/lvgl/examples/widgets/table/lv_example_table_1.py53
-rw-r--r--lib/lvgl/examples/widgets/table/lv_example_table_2.c103
-rw-r--r--lib/lvgl/examples/widgets/table/lv_example_table_2.py95
-rw-r--r--lib/lvgl/examples/widgets/tabview/index.rst14
-rw-r--r--lib/lvgl/examples/widgets/tabview/lv_example_tabview_1.c42
-rw-r--r--lib/lvgl/examples/widgets/tabview/lv_example_tabview_1.py35
-rw-r--r--lib/lvgl/examples/widgets/tabview/lv_example_tabview_2.c56
-rw-r--r--lib/lvgl/examples/widgets/tabview/lv_example_tabview_2.py48
-rw-r--r--lib/lvgl/examples/widgets/textarea/index.rst20
-rw-r--r--lib/lvgl/examples/widgets/textarea/lv_example_textarea_1.c44
-rw-r--r--lib/lvgl/examples/widgets/textarea/lv_example_textarea_1.py32
-rw-r--r--lib/lvgl/examples/widgets/textarea/lv_example_textarea_2.c59
-rw-r--r--lib/lvgl/examples/widgets/textarea/lv_example_textarea_2.py49
-rw-r--r--lib/lvgl/examples/widgets/textarea/lv_example_textarea_3.c41
-rw-r--r--lib/lvgl/examples/widgets/textarea/lv_example_textarea_3.py50
-rw-r--r--lib/lvgl/examples/widgets/tileview/index.rst7
-rw-r--r--lib/lvgl/examples/widgets/tileview/lv_example_tileview_1.c49
-rw-r--r--lib/lvgl/examples/widgets/tileview/lv_example_tileview_1.py39
-rw-r--r--lib/lvgl/examples/widgets/win/index.rst7
-rw-r--r--lib/lvgl/examples/widgets/win/lv_example_win_1.c45
-rw-r--r--lib/lvgl/examples/widgets/win/lv_example_win_1.py36
192 files changed, 8407 insertions, 0 deletions
diff --git a/lib/lvgl b/lib/lvgl
deleted file mode 160000
-Subproject 0732400e7b564dd0e7dc4a924619d8e19c5b23a
diff --git a/lib/lvgl/examples/widgets/animimg/index.rst b/lib/lvgl/examples/widgets/animimg/index.rst
new file mode 100644
index 00000000..d36a9498
--- /dev/null
+++ b/lib/lvgl/examples/widgets/animimg/index.rst
@@ -0,0 +1,7 @@
+
+Simple Animation Image
+""""""""""""""""
+
+.. lv_example:: widgets/animimg/lv_example_animimg_1
+ :language: c
+ :description: A simple example to demonstrate the use of an animation image.
diff --git a/lib/lvgl/examples/widgets/animimg/lv_example_animimg_1.c b/lib/lvgl/examples/widgets/animimg/lv_example_animimg_1.c
new file mode 100644
index 00000000..84ea9650
--- /dev/null
+++ b/lib/lvgl/examples/widgets/animimg/lv_example_animimg_1.c
@@ -0,0 +1,23 @@
+#include "../../lv_examples.h"
+#if LV_USE_ANIMIMG && LV_BUILD_EXAMPLES
+LV_IMG_DECLARE(animimg001)
+LV_IMG_DECLARE(animimg002)
+LV_IMG_DECLARE(animimg003)
+
+static const lv_img_dsc_t * anim_imgs[3] = {
+ &animimg001,
+ &animimg002,
+ &animimg003,
+};
+
+void lv_example_animimg_1(void)
+{
+ lv_obj_t * animimg0 = lv_animimg_create(lv_scr_act());
+ lv_obj_center(animimg0);
+ lv_animimg_set_src(animimg0, (lv_img_dsc_t **) anim_imgs, 3);
+ lv_animimg_set_duration(animimg0, 1000);
+ lv_animimg_set_repeat_count(animimg0, LV_ANIM_REPEAT_INFINITE);
+ lv_animimg_start(animimg0);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/animimg/lv_example_animimg_1.py b/lib/lvgl/examples/widgets/animimg/lv_example_animimg_1.py
new file mode 100644
index 00000000..f3a31fd0
--- /dev/null
+++ b/lib/lvgl/examples/widgets/animimg/lv_example_animimg_1.py
@@ -0,0 +1,54 @@
+from imagetools import get_png_info, open_png
+
+# Register PNG image decoder
+decoder = lv.img.decoder_create()
+decoder.info_cb = get_png_info
+decoder.open_cb = open_png
+
+anim_imgs = [None]*3
+# Create an image from the png file
+try:
+ with open('../../assets/animimg001.png','rb') as f:
+ anim001_data = f.read()
+except:
+ print("Could not find animimg001.png")
+ sys.exit()
+
+anim_imgs[0] = lv.img_dsc_t({
+ 'data_size': len(anim001_data),
+ 'data': anim001_data
+})
+
+try:
+ with open('../../assets/animimg002.png','rb') as f:
+ anim002_data = f.read()
+except:
+ print("Could not find animimg002.png")
+ sys.exit()
+
+anim_imgs[1] = lv.img_dsc_t({
+ 'data_size': len(anim002_data),
+ 'data': anim002_data
+})
+
+try:
+ with open('../../assets/animimg003.png','rb') as f:
+ anim003_data = f.read()
+except:
+ print("Could not find animimg003.png")
+ sys.exit()
+
+anim_imgs[2] = lv.img_dsc_t({
+ 'data_size': len(anim003_data),
+ 'data': anim003_data
+})
+
+animimg0 = lv.animimg(lv.scr_act())
+animimg0.center()
+animimg0.set_src(anim_imgs, 3)
+animimg0.set_duration(1000)
+animimg0.set_repeat_count(lv.ANIM_REPEAT.INFINITE)
+animimg0.start()
+
+
+
diff --git a/lib/lvgl/examples/widgets/arc/index.rst b/lib/lvgl/examples/widgets/arc/index.rst
new file mode 100644
index 00000000..8dea69d5
--- /dev/null
+++ b/lib/lvgl/examples/widgets/arc/index.rst
@@ -0,0 +1,14 @@
+
+Simple Arc
+""""""""""""""""
+
+.. lv_example:: widgets/arc/lv_example_arc_1
+ :language: c
+ :description: A simple example to demonstrate the use of an arc.
+
+Loader with Arc
+""""""""""""""""
+
+.. lv_example:: widgets/arc/lv_example_arc_2
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/arc/lv_example_arc_1.c b/lib/lvgl/examples/widgets/arc/lv_example_arc_1.c
new file mode 100644
index 00000000..e1ff4e86
--- /dev/null
+++ b/lib/lvgl/examples/widgets/arc/lv_example_arc_1.c
@@ -0,0 +1,35 @@
+#include "../../lv_examples.h"
+
+#if LV_USE_ARC && LV_BUILD_EXAMPLES
+
+static void value_changed_event_cb(lv_event_t * e);
+
+void lv_example_arc_1(void)
+{
+ lv_obj_t * label = lv_label_create(lv_scr_act());
+
+ /*Create an Arc*/
+ lv_obj_t * arc = lv_arc_create(lv_scr_act());
+ lv_obj_set_size(arc, 150, 150);
+ lv_arc_set_rotation(arc, 135);
+ lv_arc_set_bg_angles(arc, 0, 270);
+ lv_arc_set_value(arc, 10);
+ lv_obj_center(arc);
+ lv_obj_add_event_cb(arc, value_changed_event_cb, LV_EVENT_VALUE_CHANGED, label);
+
+ /*Manually update the label for the first time*/
+ lv_event_send(arc, LV_EVENT_VALUE_CHANGED, NULL);
+}
+
+static void value_changed_event_cb(lv_event_t * e)
+{
+ lv_obj_t * arc = lv_event_get_target(e);
+ lv_obj_t * label = lv_event_get_user_data(e);
+
+ lv_label_set_text_fmt(label, "%d%%", lv_arc_get_value(arc));
+
+ /*Rotate the label to the current position of the arc*/
+ lv_arc_rotate_obj_to_angle(arc, label, 25);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/arc/lv_example_arc_1.py b/lib/lvgl/examples/widgets/arc/lv_example_arc_1.py
new file mode 100644
index 00000000..5220b548
--- /dev/null
+++ b/lib/lvgl/examples/widgets/arc/lv_example_arc_1.py
@@ -0,0 +1,8 @@
+# Create an Arc
+arc = lv.arc(lv.scr_act())
+arc.set_end_angle(200)
+arc.set_size(150, 150)
+arc.center()
+
+
+
diff --git a/lib/lvgl/examples/widgets/arc/lv_example_arc_2.c b/lib/lvgl/examples/widgets/arc/lv_example_arc_2.c
new file mode 100644
index 00000000..3b94a75e
--- /dev/null
+++ b/lib/lvgl/examples/widgets/arc/lv_example_arc_2.c
@@ -0,0 +1,37 @@
+#include "../../lv_examples.h"
+
+#if LV_USE_ARC && LV_BUILD_EXAMPLES
+
+static void set_angle(void * obj, int32_t v)
+{
+ lv_arc_set_value(obj, v);
+}
+
+/**
+ * Create an arc which acts as a loader.
+ */
+void lv_example_arc_2(void)
+{
+ /*Create an Arc*/
+ lv_obj_t * arc = lv_arc_create(lv_scr_act());
+ lv_arc_set_rotation(arc, 270);
+ lv_arc_set_bg_angles(arc, 0, 360);
+ lv_obj_remove_style(arc, NULL, LV_PART_KNOB); /*Be sure the knob is not displayed*/
+ lv_obj_clear_flag(arc, LV_OBJ_FLAG_CLICKABLE); /*To not allow adjusting by click*/
+ lv_obj_center(arc);
+
+ lv_anim_t a;
+ lv_anim_init(&a);
+ lv_anim_set_var(&a, arc);
+ lv_anim_set_exec_cb(&a, set_angle);
+ lv_anim_set_time(&a, 1000);
+ lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE); /*Just for the demo*/
+ lv_anim_set_repeat_delay(&a, 500);
+ lv_anim_set_values(&a, 0, 100);
+ lv_anim_start(&a);
+
+
+
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/arc/lv_example_arc_2.py b/lib/lvgl/examples/widgets/arc/lv_example_arc_2.py
new file mode 100644
index 00000000..91336e2a
--- /dev/null
+++ b/lib/lvgl/examples/widgets/arc/lv_example_arc_2.py
@@ -0,0 +1,37 @@
+#
+# An `lv_timer` to call periodically to set the angles of the arc
+#
+class ArcLoader():
+ def __init__(self):
+ self.a = 270
+
+ def arc_loader_cb(self,tim,arc):
+ # print(tim,arc)
+ self.a += 5
+
+ arc.set_end_angle(self.a)
+
+ if self.a >= 270 + 360:
+ tim._del()
+
+
+#
+# Create an arc which acts as a loader.
+#
+
+# Create an Arc
+arc = lv.arc(lv.scr_act())
+arc.set_bg_angles(0, 360)
+arc.set_angles(270, 270)
+arc.center()
+
+# create the loader
+arc_loader = ArcLoader()
+
+# Create an `lv_timer` to update the arc.
+
+timer = lv.timer_create_basic()
+timer.set_period(20)
+timer.set_cb(lambda src: arc_loader.arc_loader_cb(timer,arc))
+
+
diff --git a/lib/lvgl/examples/widgets/bar/index.rst b/lib/lvgl/examples/widgets/bar/index.rst
new file mode 100644
index 00000000..4c4bb850
--- /dev/null
+++ b/lib/lvgl/examples/widgets/bar/index.rst
@@ -0,0 +1,36 @@
+Simple Bar
+""""""""""""""""
+
+.. lv_example:: widgets/bar/lv_example_bar_1
+ :language: c
+
+Styling a bar
+""""""""""""""""
+
+.. lv_example:: widgets/bar/lv_example_bar_2
+ :language: c
+
+Temperature meter
+""""""""""""""""""
+
+.. lv_example:: widgets/bar/lv_example_bar_3
+ :language: c
+
+Stripe pattern and range value
+""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/bar/lv_example_bar_4
+ :language: c
+
+Bar with LTR and RTL base direction
+""""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/bar/lv_example_bar_5
+ :language: c
+
+Custom drawer to show the current value
+"""""""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/bar/lv_example_bar_6
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/bar/lv_example_bar_1.c b/lib/lvgl/examples/widgets/bar/lv_example_bar_1.c
new file mode 100644
index 00000000..3ea98ab9
--- /dev/null
+++ b/lib/lvgl/examples/widgets/bar/lv_example_bar_1.c
@@ -0,0 +1,12 @@
+#include "../../lv_examples.h"
+#if LV_USE_BAR && LV_BUILD_EXAMPLES
+
+void lv_example_bar_1(void)
+{
+ lv_obj_t * bar1 = lv_bar_create(lv_scr_act());
+ lv_obj_set_size(bar1, 200, 20);
+ lv_obj_center(bar1);
+ lv_bar_set_value(bar1, 70, LV_ANIM_OFF);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/bar/lv_example_bar_1.py b/lib/lvgl/examples/widgets/bar/lv_example_bar_1.py
new file mode 100644
index 00000000..874e3d75
--- /dev/null
+++ b/lib/lvgl/examples/widgets/bar/lv_example_bar_1.py
@@ -0,0 +1,5 @@
+bar1 = lv.bar(lv.scr_act())
+bar1.set_size(200, 20)
+bar1.center()
+bar1.set_value(70, lv.ANIM.OFF)
+
diff --git a/lib/lvgl/examples/widgets/bar/lv_example_bar_2.c b/lib/lvgl/examples/widgets/bar/lv_example_bar_2.c
new file mode 100644
index 00000000..2688cc2d
--- /dev/null
+++ b/lib/lvgl/examples/widgets/bar/lv_example_bar_2.c
@@ -0,0 +1,34 @@
+#include "../../lv_examples.h"
+#if LV_USE_BAR && LV_BUILD_EXAMPLES
+
+/**
+ * Example of styling the bar
+ */
+void lv_example_bar_2(void)
+{
+ static lv_style_t style_bg;
+ static lv_style_t style_indic;
+
+ lv_style_init(&style_bg);
+ lv_style_set_border_color(&style_bg, lv_palette_main(LV_PALETTE_BLUE));
+ lv_style_set_border_width(&style_bg, 2);
+ lv_style_set_pad_all(&style_bg, 6); /*To make the indicator smaller*/
+ lv_style_set_radius(&style_bg, 6);
+ lv_style_set_anim_time(&style_bg, 1000);
+
+ lv_style_init(&style_indic);
+ lv_style_set_bg_opa(&style_indic, LV_OPA_COVER);
+ lv_style_set_bg_color(&style_indic, lv_palette_main(LV_PALETTE_BLUE));
+ lv_style_set_radius(&style_indic, 3);
+
+ lv_obj_t * bar = lv_bar_create(lv_scr_act());
+ lv_obj_remove_style_all(bar); /*To have a clean start*/
+ lv_obj_add_style(bar, &style_bg, 0);
+ lv_obj_add_style(bar, &style_indic, LV_PART_INDICATOR);
+
+ lv_obj_set_size(bar, 200, 20);
+ lv_obj_center(bar);
+ lv_bar_set_value(bar, 100, LV_ANIM_ON);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/bar/lv_example_bar_2.py b/lib/lvgl/examples/widgets/bar/lv_example_bar_2.py
new file mode 100644
index 00000000..37dbc0d6
--- /dev/null
+++ b/lib/lvgl/examples/widgets/bar/lv_example_bar_2.py
@@ -0,0 +1,27 @@
+#
+# Example of styling the bar
+#
+style_bg = lv.style_t()
+style_indic = lv.style_t()
+
+style_bg.init()
+style_bg.set_border_color(lv.palette_main(lv.PALETTE.BLUE))
+style_bg.set_border_width(2)
+style_bg.set_pad_all(6) # To make the indicator smaller
+style_bg.set_radius(6)
+style_bg.set_anim_time(1000)
+
+style_indic.init()
+style_indic.set_bg_opa(lv.OPA.COVER)
+style_indic.set_bg_color(lv.palette_main(lv.PALETTE.BLUE))
+style_indic.set_radius(3)
+
+bar = lv.bar(lv.scr_act())
+bar.remove_style_all() # To have a clean start
+bar.add_style(style_bg, 0)
+bar.add_style(style_indic, lv.PART.INDICATOR)
+
+bar.set_size(200, 20)
+bar.center()
+bar.set_value(100, lv.ANIM.ON)
+
diff --git a/lib/lvgl/examples/widgets/bar/lv_example_bar_3.c b/lib/lvgl/examples/widgets/bar/lv_example_bar_3.c
new file mode 100644
index 00000000..eaa8487a
--- /dev/null
+++ b/lib/lvgl/examples/widgets/bar/lv_example_bar_3.c
@@ -0,0 +1,40 @@
+#include "../../lv_examples.h"
+#if LV_USE_BAR && LV_BUILD_EXAMPLES
+
+static void set_temp(void * bar, int32_t temp)
+{
+ lv_bar_set_value(bar, temp, LV_ANIM_ON);
+}
+
+/**
+ * A temperature meter example
+ */
+void lv_example_bar_3(void)
+{
+ static lv_style_t style_indic;
+
+ lv_style_init(&style_indic);
+ lv_style_set_bg_opa(&style_indic, LV_OPA_COVER);
+ lv_style_set_bg_color(&style_indic, lv_palette_main(LV_PALETTE_RED));
+ lv_style_set_bg_grad_color(&style_indic, lv_palette_main(LV_PALETTE_BLUE));
+ lv_style_set_bg_grad_dir(&style_indic, LV_GRAD_DIR_VER);
+
+ lv_obj_t * bar = lv_bar_create(lv_scr_act());
+ lv_obj_add_style(bar, &style_indic, LV_PART_INDICATOR);
+ lv_obj_set_size(bar, 20, 200);
+ lv_obj_center(bar);
+ lv_bar_set_range(bar, -20, 40);
+
+ lv_anim_t a;
+ lv_anim_init(&a);
+ lv_anim_set_exec_cb(&a, set_temp);
+ lv_anim_set_time(&a, 3000);
+ lv_anim_set_playback_time(&a, 3000);
+ lv_anim_set_var(&a, bar);
+ lv_anim_set_values(&a, -20, 40);
+ lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
+ lv_anim_start(&a);
+}
+
+
+#endif
diff --git a/lib/lvgl/examples/widgets/bar/lv_example_bar_3.py b/lib/lvgl/examples/widgets/bar/lv_example_bar_3.py
new file mode 100644
index 00000000..c5f52f39
--- /dev/null
+++ b/lib/lvgl/examples/widgets/bar/lv_example_bar_3.py
@@ -0,0 +1,32 @@
+def set_temp(bar, temp):
+ bar.set_value(temp, lv.ANIM.ON)
+
+#
+# A temperature meter example
+#
+
+
+style_indic = lv.style_t()
+
+style_indic.init()
+style_indic.set_bg_opa(lv.OPA.COVER)
+style_indic.set_bg_color(lv.palette_main(lv.PALETTE.RED))
+style_indic.set_bg_grad_color(lv.palette_main(lv.PALETTE.BLUE))
+style_indic.set_bg_grad_dir(lv.GRAD_DIR.VER)
+
+bar = lv.bar(lv.scr_act())
+bar.add_style(style_indic, lv.PART.INDICATOR)
+bar.set_size(20, 200)
+bar.center()
+bar.set_range(-20, 40)
+
+a = lv.anim_t()
+a.init()
+a.set_time(3000)
+a.set_playback_time(3000)
+a.set_var(bar)
+a.set_values(-20, 40)
+a.set_repeat_count(lv.ANIM_REPEAT.INFINITE)
+a.set_custom_exec_cb(lambda a, val: set_temp(bar,val))
+lv.anim_t.start(a)
+
diff --git a/lib/lvgl/examples/widgets/bar/lv_example_bar_4.c b/lib/lvgl/examples/widgets/bar/lv_example_bar_4.c
new file mode 100644
index 00000000..f9abdf93
--- /dev/null
+++ b/lib/lvgl/examples/widgets/bar/lv_example_bar_4.c
@@ -0,0 +1,27 @@
+#include "../../lv_examples.h"
+#if LV_USE_BAR && LV_BUILD_EXAMPLES
+
+/**
+ * Bar with stripe pattern and ranged value
+ */
+void lv_example_bar_4(void)
+{
+ LV_IMG_DECLARE(img_skew_strip);
+ static lv_style_t style_indic;
+
+ lv_style_init(&style_indic);
+ lv_style_set_bg_img_src(&style_indic, &img_skew_strip);
+ lv_style_set_bg_img_tiled(&style_indic, true);
+ lv_style_set_bg_img_opa(&style_indic, LV_OPA_30);
+
+ lv_obj_t * bar = lv_bar_create(lv_scr_act());
+ lv_obj_add_style(bar, &style_indic, LV_PART_INDICATOR);
+
+ lv_obj_set_size(bar, 260, 20);
+ lv_obj_center(bar);
+ lv_bar_set_mode(bar, LV_BAR_MODE_RANGE);
+ lv_bar_set_value(bar, 90, LV_ANIM_OFF);
+ lv_bar_set_start_value(bar, 20, LV_ANIM_OFF);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/bar/lv_example_bar_4.py b/lib/lvgl/examples/widgets/bar/lv_example_bar_4.py
new file mode 100644
index 00000000..dcfb1924
--- /dev/null
+++ b/lib/lvgl/examples/widgets/bar/lv_example_bar_4.py
@@ -0,0 +1,45 @@
+#
+# get an icon
+#
+def get_icon(filename,xres,yres):
+ try:
+ sdl_filename = "../../assets/" + filename + "_" + str(xres) + "x" + str(yres) + "_argb8888.fnt"
+ print("file name: ", sdl_filename)
+ with open(sdl_filename,'rb') as f:
+ icon_data = f.read()
+ except:
+ print("Could not find image file: " + filename)
+ return None
+
+ icon_dsc = lv.img_dsc_t(
+ {
+ "header": {"always_zero": 0, "w": xres, "h": yres, "cf": lv.img.CF.TRUE_COLOR_ALPHA},
+ "data": icon_data,
+ "data_size": len(icon_data),
+ }
+ )
+ return icon_dsc
+
+#
+# Bar with stripe pattern and ranged value
+#
+
+img_skew_strip_dsc = get_icon("img_skew_strip",80,20)
+style_indic = lv.style_t()
+
+style_indic.init()
+style_indic.set_bg_img_src(img_skew_strip_dsc)
+style_indic.set_bg_img_tiled(True)
+style_indic.set_bg_img_opa(lv.OPA._30)
+
+bar = lv.bar(lv.scr_act())
+bar.add_style(style_indic, lv.PART.INDICATOR)
+
+bar.set_size(260, 20)
+bar.center()
+bar.set_mode(lv.bar.MODE.RANGE)
+bar.set_value(90, lv.ANIM.OFF)
+bar.set_start_value(20, lv.ANIM.OFF)
+
+
+
diff --git a/lib/lvgl/examples/widgets/bar/lv_example_bar_5.c b/lib/lvgl/examples/widgets/bar/lv_example_bar_5.c
new file mode 100644
index 00000000..c416380a
--- /dev/null
+++ b/lib/lvgl/examples/widgets/bar/lv_example_bar_5.c
@@ -0,0 +1,32 @@
+#include "../../lv_examples.h"
+#if LV_USE_BAR && LV_BUILD_EXAMPLES
+
+/**
+ * Bar with LTR and RTL base direction
+ */
+void lv_example_bar_5(void)
+{
+ lv_obj_t * label;
+
+
+ lv_obj_t * bar_ltr = lv_bar_create(lv_scr_act());
+ lv_obj_set_size(bar_ltr, 200, 20);
+ lv_bar_set_value(bar_ltr, 70, LV_ANIM_OFF);
+ lv_obj_align(bar_ltr, LV_ALIGN_CENTER, 0, -30);
+
+ label = lv_label_create(lv_scr_act());
+ lv_label_set_text(label, "Left to Right base direction");
+ lv_obj_align_to(label, bar_ltr, LV_ALIGN_OUT_TOP_MID, 0, -5);
+
+ lv_obj_t * bar_rtl = lv_bar_create(lv_scr_act());
+ lv_obj_set_style_base_dir(bar_rtl, LV_BASE_DIR_RTL, 0);
+ lv_obj_set_size(bar_rtl, 200, 20);
+ lv_bar_set_value(bar_rtl, 70, LV_ANIM_OFF);
+ lv_obj_align(bar_rtl, LV_ALIGN_CENTER, 0, 30);
+
+ label = lv_label_create(lv_scr_act());
+ lv_label_set_text(label, "Right to Left base direction");
+ lv_obj_align_to(label, bar_rtl, LV_ALIGN_OUT_TOP_MID, 0, -5);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/bar/lv_example_bar_5.py b/lib/lvgl/examples/widgets/bar/lv_example_bar_5.py
new file mode 100644
index 00000000..7c81ec8b
--- /dev/null
+++ b/lib/lvgl/examples/widgets/bar/lv_example_bar_5.py
@@ -0,0 +1,22 @@
+#
+# Bar with LTR and RTL base direction
+#
+
+bar_ltr = lv.bar(lv.scr_act())
+bar_ltr.set_size(200, 20)
+bar_ltr.set_value(70, lv.ANIM.OFF)
+bar_ltr.align(lv.ALIGN.CENTER, 0, -30)
+
+label = lv.label(lv.scr_act())
+label.set_text("Left to Right base direction")
+label.align_to(bar_ltr, lv.ALIGN.OUT_TOP_MID, 0, -5)
+
+bar_rtl = lv.bar(lv.scr_act())
+bar_rtl.set_style_base_dir(lv.BASE_DIR.RTL,0)
+bar_rtl.set_size(200, 20)
+bar_rtl.set_value(70, lv.ANIM.OFF)
+bar_rtl.align(lv.ALIGN.CENTER, 0, 30)
+
+label = lv.label(lv.scr_act())
+label.set_text("Right to Left base direction")
+label.align_to(bar_rtl, lv.ALIGN.OUT_TOP_MID, 0, -5)
diff --git a/lib/lvgl/examples/widgets/bar/lv_example_bar_6.c b/lib/lvgl/examples/widgets/bar/lv_example_bar_6.c
new file mode 100644
index 00000000..2a159cc5
--- /dev/null
+++ b/lib/lvgl/examples/widgets/bar/lv_example_bar_6.c
@@ -0,0 +1,69 @@
+#include "../../lv_examples.h"
+#if LV_USE_BAR && LV_BUILD_EXAMPLES
+
+static void set_value(void * bar, int32_t v)
+{
+ lv_bar_set_value(bar, v, LV_ANIM_OFF);
+}
+
+static void event_cb(lv_event_t * e)
+{
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+ if(dsc->part != LV_PART_INDICATOR) return;
+
+ lv_obj_t * obj = lv_event_get_target(e);
+
+ lv_draw_label_dsc_t label_dsc;
+ lv_draw_label_dsc_init(&label_dsc);
+ label_dsc.font = LV_FONT_DEFAULT;
+
+ char buf[8];
+ lv_snprintf(buf, sizeof(buf), "%d", (int)lv_bar_get_value(obj));
+
+ lv_point_t txt_size;
+ lv_txt_get_size(&txt_size, buf, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX,
+ label_dsc.flag);
+
+ lv_area_t txt_area;
+ /*If the indicator is long enough put the text inside on the right*/
+ if(lv_area_get_width(dsc->draw_area) > txt_size.x + 20) {
+ txt_area.x2 = dsc->draw_area->x2 - 5;
+ txt_area.x1 = txt_area.x2 - txt_size.x + 1;
+ label_dsc.color = lv_color_white();
+ }
+ /*If the indicator is still short put the text out of it on the right*/
+ else {
+ txt_area.x1 = dsc->draw_area->x2 + 5;
+ txt_area.x2 = txt_area.x1 + txt_size.x - 1;
+ label_dsc.color = lv_color_black();
+ }
+
+ txt_area.y1 = dsc->draw_area->y1 + (lv_area_get_height(dsc->draw_area) - txt_size.y) / 2;
+ txt_area.y2 = txt_area.y1 + txt_size.y - 1;
+
+ lv_draw_label(dsc->draw_ctx, &label_dsc, &txt_area, buf, NULL);
+}
+
+/**
+ * Custom drawer on the bar to display the current value
+ */
+void lv_example_bar_6(void)
+{
+ lv_obj_t * bar = lv_bar_create(lv_scr_act());
+ lv_obj_add_event_cb(bar, event_cb, LV_EVENT_DRAW_PART_END, NULL);
+ lv_obj_set_size(bar, 200, 20);
+ lv_obj_center(bar);
+
+ lv_anim_t a;
+ lv_anim_init(&a);
+ lv_anim_set_var(&a, bar);
+ lv_anim_set_values(&a, 0, 100);
+ lv_anim_set_exec_cb(&a, set_value);
+ lv_anim_set_time(&a, 2000);
+ lv_anim_set_playback_time(&a, 2000);
+ lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
+ lv_anim_start(&a);
+
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/bar/lv_example_bar_6.py b/lib/lvgl/examples/widgets/bar/lv_example_bar_6.py
new file mode 100644
index 00000000..9d68a871
--- /dev/null
+++ b/lib/lvgl/examples/widgets/bar/lv_example_bar_6.py
@@ -0,0 +1,54 @@
+def set_value(bar, v):
+ bar.set_value(v, lv.ANIM.OFF)
+
+def event_cb(e):
+ dsc = lv.obj_draw_part_dsc_t.__cast__(e.get_param())
+ if dsc.part != lv.PART.INDICATOR:
+ return
+
+ obj= e.get_target()
+
+ label_dsc = lv.draw_label_dsc_t()
+ label_dsc.init()
+ # label_dsc.font = LV_FONT_DEFAULT;
+
+ value_txt = str(obj.get_value())
+ txt_size = lv.point_t()
+ lv.txt_get_size(txt_size, value_txt, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, lv.COORD.MAX, label_dsc.flag)
+
+ txt_area = lv.area_t()
+ # If the indicator is long enough put the text inside on the right
+ if dsc.draw_area.get_width() > txt_size.x + 20:
+ txt_area.x2 = dsc.draw_area.x2 - 5
+ txt_area.x1 = txt_area.x2 - txt_size.x + 1
+ label_dsc.color = lv.color_white()
+ # If the indicator is still short put the text out of it on the right*/
+ else:
+ txt_area.x1 = dsc.draw_area.x2 + 5
+ txt_area.x2 = txt_area.x1 + txt_size.x - 1
+ label_dsc.color = lv.color_black()
+
+ txt_area.y1 = dsc.draw_area.y1 + (dsc.draw_area.get_height() - txt_size.y) // 2
+ txt_area.y2 = txt_area.y1 + txt_size.y - 1
+
+ dsc.draw_ctx.label(label_dsc, txt_area, value_txt, None)
+
+#
+# Custom drawer on the bar to display the current value
+#
+
+bar = lv.bar(lv.scr_act())
+bar.add_event_cb(event_cb, lv.EVENT.DRAW_PART_END, None)
+bar.set_size(200, 20)
+bar.center()
+
+a = lv.anim_t()
+a.init()
+a.set_var(bar)
+a.set_values(0, 100)
+a.set_custom_exec_cb(lambda a,val: set_value(bar,val))
+a.set_time(2000)
+a.set_playback_time(2000)
+a.set_repeat_count(lv.ANIM_REPEAT.INFINITE)
+lv.anim_t.start(a)
+
diff --git a/lib/lvgl/examples/widgets/bar/test.py b/lib/lvgl/examples/widgets/bar/test.py
new file mode 100644
index 00000000..b7843558
--- /dev/null
+++ b/lib/lvgl/examples/widgets/bar/test.py
@@ -0,0 +1,57 @@
+#!/opt/bin/lv_micropython -i
+import lvgl as lv
+import display_driver
+def set_value(bar, v):
+ bar.set_value(v, lv.ANIM.OFF)
+
+def event_cb(e):
+ dsc = lv.obj_draw_part_dsc_t.__cast__(e.get_param())
+ if dsc.part != lv.PART.INDICATOR:
+ return
+
+ obj= e.get_target()
+
+ label_dsc = lv.draw_label_dsc_t()
+ label_dsc.init()
+ # label_dsc.font = LV_FONT_DEFAULT;
+
+ value_txt = str(obj.get_value())
+ txt_size = lv.point_t()
+ lv.txt_get_size(txt_size, value_txt, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, lv.COORD.MAX, label_dsc.flag)
+
+ txt_area = lv.area_t()
+ # If the indicator is long enough put the text inside on the right
+ if dsc.draw_area.get_width() > txt_size.x + 20:
+ txt_area.x2 = dsc.draw_area.x2 - 5
+ txt_area.x1 = txt_area.x2 - txt_size.x + 1
+ label_dsc.color = lv.color_white()
+ # If the indicator is still short put the text out of it on the right*/
+ else:
+ txt_area.x1 = dsc.draw_area.x2 + 5
+ txt_area.x2 = txt_area.x1 + txt_size.x - 1
+ label_dsc.color = lv.color_black()
+
+ txt_area.y1 = dsc.draw_area.y1 + (dsc.draw_area.get_height() - txt_size.y) // 2
+ txt_area.y2 = txt_area.y1 + txt_size.y - 1
+
+ dsc.draw_ctx.label(label_dsc, txt_area, value_txt, None)
+
+#
+# Custom drawer on the bar to display the current value
+#
+
+bar = lv.bar(lv.scr_act())
+bar.add_event_cb(event_cb, lv.EVENT.DRAW_PART_END, None)
+bar.set_size(200, 20)
+bar.center()
+
+a = lv.anim_t()
+a.init()
+a.set_var(bar)
+a.set_values(0, 100)
+a.set_custom_exec_cb(lambda a,val: set_value(bar,val))
+a.set_time(2000)
+a.set_playback_time(2000)
+a.set_repeat_count(lv.ANIM_REPEAT.INFINITE)
+lv.anim_t.start(a)
+
diff --git a/lib/lvgl/examples/widgets/btn/index.rst b/lib/lvgl/examples/widgets/btn/index.rst
new file mode 100644
index 00000000..de4adb11
--- /dev/null
+++ b/lib/lvgl/examples/widgets/btn/index.rst
@@ -0,0 +1,20 @@
+
+Simple Buttons
+""""""""""""""""
+
+.. lv_example:: widgets/btn/lv_example_btn_1
+ :language: c
+
+
+Styling buttons
+""""""""""""""""
+
+.. lv_example:: widgets/btn/lv_example_btn_2
+ :language: c
+
+Gummy button
+""""""""""""""""
+
+.. lv_example:: widgets/btn/lv_example_btn_3
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/btn/lv_example_btn_1.c b/lib/lvgl/examples/widgets/btn/lv_example_btn_1.c
new file mode 100644
index 00000000..1845e209
--- /dev/null
+++ b/lib/lvgl/examples/widgets/btn/lv_example_btn_1.c
@@ -0,0 +1,38 @@
+#include "../../lv_examples.h"
+#if LV_USE_BTN && LV_BUILD_EXAMPLES
+
+static void event_handler(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+
+ if(code == LV_EVENT_CLICKED) {
+ LV_LOG_USER("Clicked");
+ }
+ else if(code == LV_EVENT_VALUE_CHANGED) {
+ LV_LOG_USER("Toggled");
+ }
+}
+
+void lv_example_btn_1(void)
+{
+ lv_obj_t * label;
+
+ lv_obj_t * btn1 = lv_btn_create(lv_scr_act());
+ lv_obj_add_event_cb(btn1, event_handler, LV_EVENT_ALL, NULL);
+ lv_obj_align(btn1, LV_ALIGN_CENTER, 0, -40);
+
+ label = lv_label_create(btn1);
+ lv_label_set_text(label, "Button");
+ lv_obj_center(label);
+
+ lv_obj_t * btn2 = lv_btn_create(lv_scr_act());
+ lv_obj_add_event_cb(btn2, event_handler, LV_EVENT_ALL, NULL);
+ lv_obj_align(btn2, LV_ALIGN_CENTER, 0, 40);
+ lv_obj_add_flag(btn2, LV_OBJ_FLAG_CHECKABLE);
+ lv_obj_set_height(btn2, LV_SIZE_CONTENT);
+
+ label = lv_label_create(btn2);
+ lv_label_set_text(label, "Toggle");
+ lv_obj_center(label);
+}
+#endif
diff --git a/lib/lvgl/examples/widgets/btn/lv_example_btn_1.py b/lib/lvgl/examples/widgets/btn/lv_example_btn_1.py
new file mode 100644
index 00000000..19fdba1d
--- /dev/null
+++ b/lib/lvgl/examples/widgets/btn/lv_example_btn_1.py
@@ -0,0 +1,32 @@
+def event_handler(evt):
+ code = evt.get_code()
+
+ if code == lv.EVENT.CLICKED:
+ print("Clicked event seen")
+ elif code == lv.EVENT.VALUE_CHANGED:
+ print("Value changed seen")
+
+# create a simple button
+btn1 = lv.btn(lv.scr_act())
+
+# attach the callback
+btn1.add_event_cb(event_handler,lv.EVENT.ALL, None)
+
+btn1.align(lv.ALIGN.CENTER,0,-40)
+label=lv.label(btn1)
+label.set_text("Button")
+
+# create a toggle button
+btn2 = lv.btn(lv.scr_act())
+
+# attach the callback
+#btn2.add_event_cb(event_handler,lv.EVENT.VALUE_CHANGED,None)
+btn2.add_event_cb(event_handler,lv.EVENT.ALL, None)
+
+btn2.align(lv.ALIGN.CENTER,0,40)
+btn2.add_flag(lv.obj.FLAG.CHECKABLE)
+btn2.set_height(lv.SIZE.CONTENT)
+
+label=lv.label(btn2)
+label.set_text("Toggle")
+label.center()
diff --git a/lib/lvgl/examples/widgets/btn/lv_example_btn_2.c b/lib/lvgl/examples/widgets/btn/lv_example_btn_2.c
new file mode 100644
index 00000000..fc32a6c1
--- /dev/null
+++ b/lib/lvgl/examples/widgets/btn/lv_example_btn_2.c
@@ -0,0 +1,65 @@
+#include "../../lv_examples.h"
+#if LV_USE_BTN && LV_BUILD_EXAMPLES
+
+/**
+ * Style a button from scratch
+ */
+void lv_example_btn_2(void)
+{
+ /*Init the style for the default state*/
+ static lv_style_t style;
+ lv_style_init(&style);
+
+ lv_style_set_radius(&style, 3);
+
+ lv_style_set_bg_opa(&style, LV_OPA_100);
+ lv_style_set_bg_color(&style, lv_palette_main(LV_PALETTE_BLUE));
+ lv_style_set_bg_grad_color(&style, lv_palette_darken(LV_PALETTE_BLUE, 2));
+ lv_style_set_bg_grad_dir(&style, LV_GRAD_DIR_VER);
+
+ lv_style_set_border_opa(&style, LV_OPA_40);
+ lv_style_set_border_width(&style, 2);
+ lv_style_set_border_color(&style, lv_palette_main(LV_PALETTE_GREY));
+
+ lv_style_set_shadow_width(&style, 8);
+ lv_style_set_shadow_color(&style, lv_palette_main(LV_PALETTE_GREY));
+ lv_style_set_shadow_ofs_y(&style, 8);
+
+ lv_style_set_outline_opa(&style, LV_OPA_COVER);
+ lv_style_set_outline_color(&style, lv_palette_main(LV_PALETTE_BLUE));
+
+ lv_style_set_text_color(&style, lv_color_white());
+ lv_style_set_pad_all(&style, 10);
+
+ /*Init the pressed style*/
+ static lv_style_t style_pr;
+ lv_style_init(&style_pr);
+
+ /*Add a large outline when pressed*/
+ lv_style_set_outline_width(&style_pr, 30);
+ lv_style_set_outline_opa(&style_pr, LV_OPA_TRANSP);
+
+ lv_style_set_translate_y(&style_pr, 5);
+ lv_style_set_shadow_ofs_y(&style_pr, 3);
+ lv_style_set_bg_color(&style_pr, lv_palette_darken(LV_PALETTE_BLUE, 2));
+ lv_style_set_bg_grad_color(&style_pr, lv_palette_darken(LV_PALETTE_BLUE, 4));
+
+ /*Add a transition to the outline*/
+ static lv_style_transition_dsc_t trans;
+ static lv_style_prop_t props[] = {LV_STYLE_OUTLINE_WIDTH, LV_STYLE_OUTLINE_OPA, 0};
+ lv_style_transition_dsc_init(&trans, props, lv_anim_path_linear, 300, 0, NULL);
+
+ lv_style_set_transition(&style_pr, &trans);
+
+ lv_obj_t * btn1 = lv_btn_create(lv_scr_act());
+ lv_obj_remove_style_all(btn1); /*Remove the style coming from the theme*/
+ lv_obj_add_style(btn1, &style, 0);
+ lv_obj_add_style(btn1, &style_pr, LV_STATE_PRESSED);
+ lv_obj_set_size(btn1, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
+ lv_obj_center(btn1);
+
+ lv_obj_t * label = lv_label_create(btn1);
+ lv_label_set_text(label, "Button");
+ lv_obj_center(label);
+}
+#endif
diff --git a/lib/lvgl/examples/widgets/btn/lv_example_btn_2.py b/lib/lvgl/examples/widgets/btn/lv_example_btn_2.py
new file mode 100644
index 00000000..38c09a1e
--- /dev/null
+++ b/lib/lvgl/examples/widgets/btn/lv_example_btn_2.py
@@ -0,0 +1,60 @@
+#
+# Style a button from scratch
+#
+
+# Init the style for the default state
+style = lv.style_t()
+style.init()
+
+style.set_radius(3)
+
+style.set_bg_opa(lv.OPA.COVER)
+style.set_bg_color(lv.palette_main(lv.PALETTE.BLUE))
+style.set_bg_grad_color(lv.palette_darken(lv.PALETTE.BLUE, 2))
+style.set_bg_grad_dir(lv.GRAD_DIR.VER)
+
+style.set_border_opa(lv.OPA._40)
+style.set_border_width(2)
+style.set_border_color(lv.palette_main(lv.PALETTE.GREY))
+
+style.set_shadow_width(8)
+style.set_shadow_color(lv.palette_main(lv.PALETTE.GREY))
+style.set_shadow_ofs_y(8)
+
+style.set_outline_opa(lv.OPA.COVER)
+style.set_outline_color(lv.palette_main(lv.PALETTE.BLUE))
+
+style.set_text_color(lv.color_white())
+style.set_pad_all(10)
+
+# Init the pressed style
+style_pr = lv.style_t()
+style_pr.init()
+
+# Add a large outline when pressed
+style_pr.set_outline_width(30)
+style_pr.set_outline_opa(lv.OPA.TRANSP)
+
+style_pr.set_translate_y(5)
+style_pr.set_shadow_ofs_y(3)
+style_pr.set_bg_color(lv.palette_darken(lv.PALETTE.BLUE, 2))
+style_pr.set_bg_grad_color(lv.palette_darken(lv.PALETTE.BLUE, 4))
+
+# Add a transition to the outline
+trans = lv.style_transition_dsc_t()
+props = [lv.STYLE.OUTLINE_WIDTH, lv.STYLE.OUTLINE_OPA, 0]
+trans.init(props, lv.anim_t.path_linear, 300, 0, None)
+
+style_pr.set_transition(trans)
+
+btn1 = lv.btn(lv.scr_act())
+btn1.remove_style_all() # Remove the style coming from the theme
+btn1.add_style(style, 0)
+btn1.add_style(style_pr, lv.STATE.PRESSED)
+btn1.set_size(lv.SIZE.CONTENT, lv.SIZE.CONTENT)
+btn1.center()
+
+label = lv.label(btn1)
+label.set_text("Button")
+label.center()
+
diff --git a/lib/lvgl/examples/widgets/btn/lv_example_btn_3.c b/lib/lvgl/examples/widgets/btn/lv_example_btn_3.c
new file mode 100644
index 00000000..24d76c34
--- /dev/null
+++ b/lib/lvgl/examples/widgets/btn/lv_example_btn_3.c
@@ -0,0 +1,45 @@
+#include "../../lv_examples.h"
+#if LV_BUILD_EXAMPLES && LV_USE_BTN
+
+/**
+ * Create a style transition on a button to act like a gum when clicked
+ */
+void lv_example_btn_3(void)
+{
+ /*Properties to transition*/
+ static lv_style_prop_t props[] = {
+ LV_STYLE_TRANSFORM_WIDTH, LV_STYLE_TRANSFORM_HEIGHT, LV_STYLE_TEXT_LETTER_SPACE, 0
+ };
+
+ /*Transition descriptor when going back to the default state.
+ *Add some delay to be sure the press transition is visible even if the press was very short*/
+ static lv_style_transition_dsc_t transition_dsc_def;
+ lv_style_transition_dsc_init(&transition_dsc_def, props, lv_anim_path_overshoot, 250, 100, NULL);
+
+ /*Transition descriptor when going to pressed state.
+ *No delay, go to presses state immediately*/
+ static lv_style_transition_dsc_t transition_dsc_pr;
+ lv_style_transition_dsc_init(&transition_dsc_pr, props, lv_anim_path_ease_in_out, 250, 0, NULL);
+
+ /*Add only the new transition to he default state*/
+ static lv_style_t style_def;
+ lv_style_init(&style_def);
+ lv_style_set_transition(&style_def, &transition_dsc_def);
+
+ /*Add the transition and some transformation to the presses state.*/
+ static lv_style_t style_pr;
+ lv_style_init(&style_pr);
+ lv_style_set_transform_width(&style_pr, 10);
+ lv_style_set_transform_height(&style_pr, -10);
+ lv_style_set_text_letter_space(&style_pr, 10);
+ lv_style_set_transition(&style_pr, &transition_dsc_pr);
+
+ lv_obj_t * btn1 = lv_btn_create(lv_scr_act());
+ lv_obj_align(btn1, LV_ALIGN_CENTER, 0, -80);
+ lv_obj_add_style(btn1, &style_pr, LV_STATE_PRESSED);
+ lv_obj_add_style(btn1, &style_def, 0);
+
+ lv_obj_t * label = lv_label_create(btn1);
+ lv_label_set_text(label, "Gum");
+}
+#endif
diff --git a/lib/lvgl/examples/widgets/btn/lv_example_btn_3.py b/lib/lvgl/examples/widgets/btn/lv_example_btn_3.py
new file mode 100644
index 00000000..ec664a6e
--- /dev/null
+++ b/lib/lvgl/examples/widgets/btn/lv_example_btn_3.py
@@ -0,0 +1,38 @@
+#
+# Create a style transition on a button to act like a gum when clicked
+#
+
+# Properties to transition
+props = [lv.STYLE.TRANSFORM_WIDTH, lv.STYLE.TRANSFORM_HEIGHT, lv.STYLE.TEXT_LETTER_SPACE, 0]
+
+# Transition descriptor when going back to the default state.
+# Add some delay to be sure the press transition is visible even if the press was very short*/
+transition_dsc_def = lv.style_transition_dsc_t()
+transition_dsc_def.init(props, lv.anim_t.path_overshoot, 250, 100, None)
+
+# Transition descriptor when going to pressed state.
+# No delay, go to pressed state immediately
+transition_dsc_pr = lv.style_transition_dsc_t()
+transition_dsc_pr.init(props, lv.anim_t.path_ease_in_out, 250, 0, None)
+
+# Add only the new transition to the default state
+style_def = lv.style_t()
+style_def.init()
+style_def.set_transition(transition_dsc_def)
+
+# Add the transition and some transformation to the presses state.
+style_pr = lv.style_t()
+style_pr.init()
+style_pr.set_transform_width(10)
+style_pr.set_transform_height(-10)
+style_pr.set_text_letter_space(10)
+style_pr.set_transition(transition_dsc_pr)
+
+btn1 = lv.btn(lv.scr_act())
+btn1.align(lv.ALIGN.CENTER, 0, -80)
+btn1.add_style(style_pr, lv.STATE.PRESSED)
+btn1.add_style(style_def, 0)
+
+label = lv.label(btn1)
+label.set_text("Gum")
+
diff --git a/lib/lvgl/examples/widgets/btnmatrix/index.rst b/lib/lvgl/examples/widgets/btnmatrix/index.rst
new file mode 100644
index 00000000..9f569eac
--- /dev/null
+++ b/lib/lvgl/examples/widgets/btnmatrix/index.rst
@@ -0,0 +1,22 @@
+
+Simple Button matrix
+""""""""""""""""""""""
+
+.. lv_example:: widgets/btnmatrix/lv_example_btnmatrix_1
+ :language: c
+
+
+Custom buttons
+""""""""""""""""""""""
+
+.. lv_example:: widgets/btnmatrix/lv_example_btnmatrix_2
+ :language: c
+
+
+Pagination
+""""""""""""""""""""""
+
+.. lv_example:: widgets/btnmatrix/lv_example_btnmatrix_3
+ :language: c
+
+
diff --git a/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_1.c b/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_1.c
new file mode 100644
index 00000000..262165ff
--- /dev/null
+++ b/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_1.c
@@ -0,0 +1,33 @@
+#include "../../lv_examples.h"
+#if LV_USE_BTNMATRIX && LV_BUILD_EXAMPLES
+
+static void event_handler(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+ if(code == LV_EVENT_VALUE_CHANGED) {
+ uint32_t id = lv_btnmatrix_get_selected_btn(obj);
+ const char * txt = lv_btnmatrix_get_btn_text(obj, id);
+
+ LV_LOG_USER("%s was pressed\n", txt);
+ }
+}
+
+
+static const char * btnm_map[] = {"1", "2", "3", "4", "5", "\n",
+ "6", "7", "8", "9", "0", "\n",
+ "Action1", "Action2", ""
+ };
+
+void lv_example_btnmatrix_1(void)
+{
+ lv_obj_t * btnm1 = lv_btnmatrix_create(lv_scr_act());
+ lv_btnmatrix_set_map(btnm1, btnm_map);
+ lv_btnmatrix_set_btn_width(btnm1, 10, 2); /*Make "Action1" twice as wide as "Action2"*/
+ lv_btnmatrix_set_btn_ctrl(btnm1, 10, LV_BTNMATRIX_CTRL_CHECKABLE);
+ lv_btnmatrix_set_btn_ctrl(btnm1, 11, LV_BTNMATRIX_CTRL_CHECKED);
+ lv_obj_align(btnm1, LV_ALIGN_CENTER, 0, 0);
+ lv_obj_add_event_cb(btnm1, event_handler, LV_EVENT_ALL, NULL);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_1.py b/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_1.py
new file mode 100644
index 00000000..9adbddff
--- /dev/null
+++ b/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_1.py
@@ -0,0 +1,24 @@
+def event_handler(evt):
+ code = evt.get_code()
+ obj = evt.get_target()
+
+ if code == lv.EVENT.VALUE_CHANGED :
+ id = obj.get_selected_btn()
+ txt = obj.get_btn_text(id)
+
+ print("%s was pressed"%txt)
+
+btnm_map = ["1", "2", "3", "4", "5", "\n",
+ "6", "7", "8", "9", "0", "\n",
+ "Action1", "Action2", ""]
+
+btnm1 = lv.btnmatrix(lv.scr_act())
+btnm1.set_map(btnm_map)
+btnm1.set_btn_width(10, 2) # Make "Action1" twice as wide as "Action2"
+btnm1.set_btn_ctrl(10, lv.btnmatrix.CTRL.CHECKABLE)
+btnm1.set_btn_ctrl(11, lv.btnmatrix.CTRL.CHECKED)
+btnm1.align(lv.ALIGN.CENTER, 0, 0)
+btnm1.add_event_cb(event_handler, lv.EVENT.ALL, None)
+
+
+#endif
diff --git a/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_2.c b/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_2.c
new file mode 100644
index 00000000..985a3d1e
--- /dev/null
+++ b/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_2.c
@@ -0,0 +1,78 @@
+#include "../../lv_examples.h"
+#if LV_USE_BTNMATRIX && LV_BUILD_EXAMPLES
+
+
+static void event_cb(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+ if(code == LV_EVENT_DRAW_PART_BEGIN) {
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+
+ /*When the button matrix draws the buttons...*/
+ if(dsc->class_p == &lv_btnmatrix_class && dsc->type == LV_BTNMATRIX_DRAW_PART_BTN) {
+ /*Change the draw descriptor of the 2nd button*/
+ if(dsc->id == 1) {
+ dsc->rect_dsc->radius = 0;
+ if(lv_btnmatrix_get_selected_btn(obj) == dsc->id) dsc->rect_dsc->bg_color = lv_palette_darken(LV_PALETTE_BLUE, 3);
+ else dsc->rect_dsc->bg_color = lv_palette_main(LV_PALETTE_BLUE);
+
+ dsc->rect_dsc->shadow_width = 6;
+ dsc->rect_dsc->shadow_ofs_x = 3;
+ dsc->rect_dsc->shadow_ofs_y = 3;
+ dsc->label_dsc->color = lv_color_white();
+ }
+ /*Change the draw descriptor of the 3rd button*/
+ else if(dsc->id == 2) {
+ dsc->rect_dsc->radius = LV_RADIUS_CIRCLE;
+ if(lv_btnmatrix_get_selected_btn(obj) == dsc->id) dsc->rect_dsc->bg_color = lv_palette_darken(LV_PALETTE_RED, 3);
+ else dsc->rect_dsc->bg_color = lv_palette_main(LV_PALETTE_RED);
+
+ dsc->label_dsc->color = lv_color_white();
+ }
+ else if(dsc->id == 3) {
+ dsc->label_dsc->opa = LV_OPA_TRANSP; /*Hide the text if any*/
+
+ }
+ }
+ }
+ if(code == LV_EVENT_DRAW_PART_END) {
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+
+ /*When the button matrix draws the buttons...*/
+ if(dsc->class_p == &lv_btnmatrix_class && dsc->type == LV_BTNMATRIX_DRAW_PART_BTN) {
+ /*Add custom content to the 4th button when the button itself was drawn*/
+ if(dsc->id == 3) {
+ LV_IMG_DECLARE(img_star);
+ lv_img_header_t header;
+ lv_res_t res = lv_img_decoder_get_info(&img_star, &header);
+ if(res != LV_RES_OK) return;
+
+ lv_area_t a;
+ a.x1 = dsc->draw_area->x1 + (lv_area_get_width(dsc->draw_area) - header.w) / 2;
+ a.x2 = a.x1 + header.w - 1;
+ a.y1 = dsc->draw_area->y1 + (lv_area_get_height(dsc->draw_area) - header.h) / 2;
+ a.y2 = a.y1 + header.h - 1;
+
+ lv_draw_img_dsc_t img_draw_dsc;
+ lv_draw_img_dsc_init(&img_draw_dsc);
+ img_draw_dsc.recolor = lv_color_black();
+ if(lv_btnmatrix_get_selected_btn(obj) == dsc->id) img_draw_dsc.recolor_opa = LV_OPA_30;
+
+ lv_draw_img(dsc->draw_ctx, &img_draw_dsc, &a, &img_star);
+ }
+ }
+ }
+}
+
+/**
+ * Add custom drawer to the button matrix to customize buttons one by one
+ */
+void lv_example_btnmatrix_2(void)
+{
+ lv_obj_t * btnm = lv_btnmatrix_create(lv_scr_act());
+ lv_obj_add_event_cb(btnm, event_cb, LV_EVENT_ALL, NULL);
+ lv_obj_center(btnm);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_2.py b/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_2.py
new file mode 100644
index 00000000..21f7c71f
--- /dev/null
+++ b/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_2.py
@@ -0,0 +1,81 @@
+from imagetools import get_png_info, open_png
+
+# Register PNG image decoder
+decoder = lv.img.decoder_create()
+decoder.info_cb = get_png_info
+decoder.open_cb = open_png
+
+# Create an image from the png file
+try:
+ with open('../../assets/img_star.png','rb') as f:
+ png_data = f.read()
+except:
+ print("Could not find star.png")
+ sys.exit()
+
+img_star_argb = lv.img_dsc_t({
+ 'data_size': len(png_data),
+ 'data': png_data
+})
+
+def event_cb(e):
+ code = e.get_code()
+ obj = e.get_target()
+ dsc = lv.obj_draw_part_dsc_t.__cast__(e.get_param())
+ if code == lv.EVENT.DRAW_PART_BEGIN:
+ # Change the draw descriptor the 2nd button
+ if dsc.id == 1:
+ dsc.rect_dsc.radius = 0
+ if obj.get_selected_btn() == dsc.id:
+ dsc.rect_dsc.bg_color = lv.palette_darken(lv.PALETTE.GREY, 3)
+ else:
+ dsc.rect_dsc.bg_color = lv.palette_main(lv.PALETTE.BLUE)
+
+ dsc.rect_dsc.shadow_width = 6
+ dsc.rect_dsc.shadow_ofs_x = 3
+ dsc.rect_dsc.shadow_ofs_y = 3
+ dsc.label_dsc.color = lv.color_white()
+
+ # Change the draw descriptor the 3rd button
+
+ elif dsc.id == 2:
+ dsc.rect_dsc.radius = lv.RADIUS.CIRCLE
+ if obj.get_selected_btn() == dsc.id:
+ dsc.rect_dsc.bg_color = lv.palette_darken(lv.PALETTE.RED, 3)
+ else:
+ dsc.rect_dsc.bg_color = lv.palette_main(lv.PALETTE.RED)
+
+ dsc.label_dsc.color = lv.color_white()
+ elif dsc.id == 3:
+ dsc.label_dsc.opa = lv.OPA.TRANSP # Hide the text if any
+
+ if code == lv.EVENT.DRAW_PART_END:
+ # Add custom content to the 4th button when the button itself was drawn
+ if dsc.id == 3:
+ # LV_IMG_DECLARE(img_star)
+ header = lv.img_header_t()
+ res = lv.img.decoder_get_info(img_star_argb, header)
+ if res != lv.RES.OK:
+ print("error when getting image header")
+ return
+ else:
+ a = lv.area_t()
+ a.x1 = dsc.draw_area.x1 + (dsc.draw_area.get_width() - header.w) // 2
+ a.x2 = a.x1 + header.w - 1
+ a.y1 = dsc.draw_area.y1 + (dsc.draw_area.get_height() - header.h) // 2
+ a.y2 = a.y1 + header.h - 1
+ img_draw_dsc = lv.draw_img_dsc_t()
+ img_draw_dsc.init()
+ img_draw_dsc.recolor = lv.color_black()
+ if obj.get_selected_btn() == dsc.id:
+ img_draw_dsc.recolor_opa = lv.OPA._30
+
+ dsc.draw_ctx.img(img_draw_dsc, a, img_star_argb)
+
+#
+# Add custom drawer to the button matrix to c
+#
+btnm = lv.btnmatrix(lv.scr_act())
+btnm.add_event_cb(event_cb, lv.EVENT.ALL, None)
+btnm.center()
+
diff --git a/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_3.c b/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_3.c
new file mode 100644
index 00000000..cbfcfbd0
--- /dev/null
+++ b/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_3.c
@@ -0,0 +1,68 @@
+#include "../../lv_examples.h"
+#if LV_USE_BTNMATRIX && LV_BUILD_EXAMPLES
+
+static void event_cb(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+ uint32_t id = lv_btnmatrix_get_selected_btn(obj);
+ bool prev = id == 0 ? true : false;
+ bool next = id == 6 ? true : false;
+ if(prev || next) {
+ /*Find the checked button*/
+ uint32_t i;
+ for(i = 1; i < 7; i++) {
+ if(lv_btnmatrix_has_btn_ctrl(obj, i, LV_BTNMATRIX_CTRL_CHECKED)) break;
+ }
+
+ if(prev && i > 1) i--;
+ else if(next && i < 5) i++;
+
+ lv_btnmatrix_set_btn_ctrl(obj, i, LV_BTNMATRIX_CTRL_CHECKED);
+ }
+}
+
+/**
+ * Make a button group (pagination)
+ */
+void lv_example_btnmatrix_3(void)
+{
+ static lv_style_t style_bg;
+ lv_style_init(&style_bg);
+ lv_style_set_pad_all(&style_bg, 0);
+ lv_style_set_pad_gap(&style_bg, 0);
+ lv_style_set_clip_corner(&style_bg, true);
+ lv_style_set_radius(&style_bg, LV_RADIUS_CIRCLE);
+ lv_style_set_border_width(&style_bg, 0);
+
+
+ static lv_style_t style_btn;
+ lv_style_init(&style_btn);
+ lv_style_set_radius(&style_btn, 0);
+ lv_style_set_border_width(&style_btn, 1);
+ lv_style_set_border_opa(&style_btn, LV_OPA_50);
+ lv_style_set_border_color(&style_btn, lv_palette_main(LV_PALETTE_GREY));
+ lv_style_set_border_side(&style_btn, LV_BORDER_SIDE_INTERNAL);
+ lv_style_set_radius(&style_btn, 0);
+
+ static const char * map[] = {LV_SYMBOL_LEFT, "1", "2", "3", "4", "5", LV_SYMBOL_RIGHT, ""};
+
+ lv_obj_t * btnm = lv_btnmatrix_create(lv_scr_act());
+ lv_btnmatrix_set_map(btnm, map);
+ lv_obj_add_style(btnm, &style_bg, 0);
+ lv_obj_add_style(btnm, &style_btn, LV_PART_ITEMS);
+ lv_obj_add_event_cb(btnm, event_cb, LV_EVENT_VALUE_CHANGED, NULL);
+ lv_obj_set_size(btnm, 225, 35);
+
+ /*Allow selecting on one number at time*/
+ lv_btnmatrix_set_btn_ctrl_all(btnm, LV_BTNMATRIX_CTRL_CHECKABLE);
+ lv_btnmatrix_clear_btn_ctrl(btnm, 0, LV_BTNMATRIX_CTRL_CHECKABLE);
+ lv_btnmatrix_clear_btn_ctrl(btnm, 6, LV_BTNMATRIX_CTRL_CHECKABLE);
+
+ lv_btnmatrix_set_one_checked(btnm, true);
+ lv_btnmatrix_set_btn_ctrl(btnm, 1, LV_BTNMATRIX_CTRL_CHECKED);
+
+ lv_obj_center(btnm);
+
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_3.py b/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_3.py
new file mode 100644
index 00000000..01c23322
--- /dev/null
+++ b/lib/lvgl/examples/widgets/btnmatrix/lv_example_btnmatrix_3.py
@@ -0,0 +1,64 @@
+def event_cb(e):
+ obj = e.get_target()
+ id = obj.get_selected_btn()
+ if id == 0:
+ prev = True
+ else:
+ prev = False
+ if id == 6:
+ next = True
+ else:
+ next = False
+ if prev or next:
+ # Find the checked butto
+ for i in range(7):
+ if obj.has_btn_ctrl(i, lv.btnmatrix.CTRL.CHECKED):
+ break
+ if prev and i > 1:
+ i-=1
+ elif next and i < 5:
+ i+=1
+
+ obj.set_btn_ctrl(i, lv.btnmatrix.CTRL.CHECKED)
+
+#
+# Make a button group
+#
+
+style_bg = lv.style_t()
+style_bg.init()
+style_bg.set_pad_all(0)
+style_bg.set_pad_gap(0)
+style_bg.set_clip_corner(True)
+style_bg.set_radius(lv.RADIUS.CIRCLE)
+style_bg.set_border_width(0)
+
+
+style_btn = lv.style_t()
+style_btn.init()
+style_btn.set_radius(0)
+style_btn.set_border_width(1)
+style_btn.set_border_opa(lv.OPA._50)
+style_btn.set_border_color(lv.palette_main(lv.PALETTE.GREY))
+style_btn.set_border_side(lv.BORDER_SIDE.INTERNAL)
+style_btn.set_radius(0)
+
+map = [lv.SYMBOL.LEFT,"1","2", "3", "4", "5",lv.SYMBOL.RIGHT, ""]
+
+btnm = lv.btnmatrix(lv.scr_act())
+btnm.set_map(map)
+btnm.add_style(style_bg, 0)
+btnm.add_style(style_btn, lv.PART.ITEMS)
+btnm.add_event_cb(event_cb, lv.EVENT.VALUE_CHANGED, None)
+btnm.set_size(225, 35)
+
+# Allow selecting on one number at time
+btnm.set_btn_ctrl_all(lv.btnmatrix.CTRL.CHECKABLE)
+btnm.clear_btn_ctrl(0, lv.btnmatrix.CTRL.CHECKABLE)
+btnm.clear_btn_ctrl(6, lv.btnmatrix.CTRL.CHECKABLE)
+
+btnm.set_one_checked(True)
+btnm.set_btn_ctrl(1, lv.btnmatrix.CTRL.CHECKED)
+
+btnm.center()
+
diff --git a/lib/lvgl/examples/widgets/calendar/index.rst b/lib/lvgl/examples/widgets/calendar/index.rst
new file mode 100644
index 00000000..831fb1e4
--- /dev/null
+++ b/lib/lvgl/examples/widgets/calendar/index.rst
@@ -0,0 +1,7 @@
+
+Calendar with header
+""""""""""""""""""""""
+
+.. lv_example:: widgets/calendar/lv_example_calendar_1
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/calendar/lv_example_calendar_1.c b/lib/lvgl/examples/widgets/calendar/lv_example_calendar_1.c
new file mode 100644
index 00000000..e76df2ed
--- /dev/null
+++ b/lib/lvgl/examples/widgets/calendar/lv_example_calendar_1.c
@@ -0,0 +1,51 @@
+#include "../../lv_examples.h"
+#if LV_USE_CALENDAR && LV_BUILD_EXAMPLES
+
+static void event_handler(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_current_target(e);
+
+ if(code == LV_EVENT_VALUE_CHANGED) {
+ lv_calendar_date_t date;
+ if(lv_calendar_get_pressed_date(obj, &date)) {
+ LV_LOG_USER("Clicked date: %02d.%02d.%d", date.day, date.month, date.year);
+ }
+ }
+}
+
+void lv_example_calendar_1(void)
+{
+ lv_obj_t * calendar = lv_calendar_create(lv_scr_act());
+ lv_obj_set_size(calendar, 185, 185);
+ lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 27);
+ lv_obj_add_event_cb(calendar, event_handler, LV_EVENT_ALL, NULL);
+
+ lv_calendar_set_today_date(calendar, 2021, 02, 23);
+ lv_calendar_set_showed_date(calendar, 2021, 02);
+
+ /*Highlight a few days*/
+ static lv_calendar_date_t highlighted_days[3]; /*Only its pointer will be saved so should be static*/
+ highlighted_days[0].year = 2021;
+ highlighted_days[0].month = 02;
+ highlighted_days[0].day = 6;
+
+ highlighted_days[1].year = 2021;
+ highlighted_days[1].month = 02;
+ highlighted_days[1].day = 11;
+
+ highlighted_days[2].year = 2022;
+ highlighted_days[2].month = 02;
+ highlighted_days[2].day = 22;
+
+ lv_calendar_set_highlighted_dates(calendar, highlighted_days, 3);
+
+#if LV_USE_CALENDAR_HEADER_DROPDOWN
+ lv_calendar_header_dropdown_create(calendar);
+#elif LV_USE_CALENDAR_HEADER_ARROW
+ lv_calendar_header_arrow_create(calendar);
+#endif
+ lv_calendar_set_showed_date(calendar, 2021, 10);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/calendar/lv_example_calendar_1.py b/lib/lvgl/examples/widgets/calendar/lv_example_calendar_1.py
new file mode 100644
index 00000000..2df024d0
--- /dev/null
+++ b/lib/lvgl/examples/widgets/calendar/lv_example_calendar_1.py
@@ -0,0 +1,30 @@
+
+def event_handler(evt):
+ code = evt.get_code()
+
+ if code == lv.EVENT.VALUE_CHANGED:
+ source = evt.get_current_target()
+ date = lv.calendar_date_t()
+ if source.get_pressed_date(date) == lv.RES.OK:
+ calendar.set_today_date(date.year, date.month, date.day)
+ print("Clicked date: %02d.%02d.%02d"%(date.day, date.month, date.year))
+
+
+calendar = lv.calendar(lv.scr_act())
+calendar.set_size(200, 200)
+calendar.align(lv.ALIGN.CENTER, 0, 20)
+calendar.add_event_cb(event_handler, lv.EVENT.ALL, None)
+
+calendar.set_today_date(2021, 02, 23)
+calendar.set_showed_date(2021, 02)
+
+# Highlight a few days
+highlighted_days=[
+ lv.calendar_date_t({'year':2021, 'month':2, 'day':6}),
+ lv.calendar_date_t({'year':2021, 'month':2, 'day':11}),
+ lv.calendar_date_t({'year':2021, 'month':2, 'day':22})
+]
+
+calendar.set_highlighted_dates(highlighted_days, len(highlighted_days))
+
+lv.calendar_header_dropdown(calendar)
diff --git a/lib/lvgl/examples/widgets/canvas/index.rst b/lib/lvgl/examples/widgets/canvas/index.rst
new file mode 100644
index 00000000..b2cd7d4d
--- /dev/null
+++ b/lib/lvgl/examples/widgets/canvas/index.rst
@@ -0,0 +1,13 @@
+
+Drawing on the Canvas and rotate
+""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/canvas/lv_example_canvas_1
+ :language: c
+
+Transparent Canvas with chroma keying
+""""""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/canvas/lv_example_canvas_2
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/canvas/lv_example_canvas_1.c b/lib/lvgl/examples/widgets/canvas/lv_example_canvas_1.c
new file mode 100644
index 00000000..6dd9ab0d
--- /dev/null
+++ b/lib/lvgl/examples/widgets/canvas/lv_example_canvas_1.c
@@ -0,0 +1,53 @@
+#include "../../lv_examples.h"
+#if LV_USE_CANVAS && LV_BUILD_EXAMPLES
+
+
+#define CANVAS_WIDTH 200
+#define CANVAS_HEIGHT 150
+
+void lv_example_canvas_1(void)
+{
+ lv_draw_rect_dsc_t rect_dsc;
+ lv_draw_rect_dsc_init(&rect_dsc);
+ rect_dsc.radius = 10;
+ rect_dsc.bg_opa = LV_OPA_COVER;
+ rect_dsc.bg_grad.dir = LV_GRAD_DIR_HOR;
+ rect_dsc.bg_grad.stops[0].color = lv_palette_main(LV_PALETTE_RED);
+ rect_dsc.bg_grad.stops[1].color = lv_palette_main(LV_PALETTE_BLUE);
+ rect_dsc.border_width = 2;
+ rect_dsc.border_opa = LV_OPA_90;
+ rect_dsc.border_color = lv_color_white();
+ rect_dsc.shadow_width = 5;
+ rect_dsc.shadow_ofs_x = 5;
+ rect_dsc.shadow_ofs_y = 5;
+
+ lv_draw_label_dsc_t label_dsc;
+ lv_draw_label_dsc_init(&label_dsc);
+ label_dsc.color = lv_palette_main(LV_PALETTE_ORANGE);
+
+ static lv_color_t cbuf[LV_CANVAS_BUF_SIZE_TRUE_COLOR(CANVAS_WIDTH, CANVAS_HEIGHT)];
+
+ lv_obj_t * canvas = lv_canvas_create(lv_scr_act());
+ lv_canvas_set_buffer(canvas, cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_IMG_CF_TRUE_COLOR);
+ lv_obj_center(canvas);
+ lv_canvas_fill_bg(canvas, lv_palette_lighten(LV_PALETTE_GREY, 3), LV_OPA_COVER);
+
+ lv_canvas_draw_rect(canvas, 70, 60, 100, 70, &rect_dsc);
+
+ lv_canvas_draw_text(canvas, 40, 20, 100, &label_dsc, "Some text on text canvas");
+
+ /*Test the rotation. It requires another buffer where the original image is stored.
+ *So copy the current image to buffer and rotate it to the canvas*/
+ static lv_color_t cbuf_tmp[CANVAS_WIDTH * CANVAS_HEIGHT];
+ memcpy(cbuf_tmp, cbuf, sizeof(cbuf_tmp));
+ lv_img_dsc_t img;
+ img.data = (void *)cbuf_tmp;
+ img.header.cf = LV_IMG_CF_TRUE_COLOR;
+ img.header.w = CANVAS_WIDTH;
+ img.header.h = CANVAS_HEIGHT;
+
+ lv_canvas_fill_bg(canvas, lv_palette_lighten(LV_PALETTE_GREY, 3), LV_OPA_COVER);
+ lv_canvas_transform(canvas, &img, 120, LV_IMG_ZOOM_NONE, 0, 0, CANVAS_WIDTH / 2, CANVAS_HEIGHT / 2, true);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/canvas/lv_example_canvas_1.py b/lib/lvgl/examples/widgets/canvas/lv_example_canvas_1.py
new file mode 100644
index 00000000..d07cee4b
--- /dev/null
+++ b/lib/lvgl/examples/widgets/canvas/lv_example_canvas_1.py
@@ -0,0 +1,43 @@
+_CANVAS_WIDTH = 200
+_CANVAS_HEIGHT = 150
+LV_IMG_ZOOM_NONE = 256
+
+rect_dsc = lv.draw_rect_dsc_t()
+rect_dsc.init()
+rect_dsc.radius = 10
+rect_dsc.bg_opa = lv.OPA.COVER
+rect_dsc.bg_grad.dir = lv.GRAD_DIR.HOR
+rect_dsc.bg_grad.stops[0].color = lv.palette_main(lv.PALETTE.RED)
+rect_dsc.bg_grad.stops[1].color = lv.palette_main(lv.PALETTE.BLUE)
+rect_dsc.border_width = 2
+rect_dsc.border_opa = lv.OPA._90
+rect_dsc.border_color = lv.color_white()
+rect_dsc.shadow_width = 5
+rect_dsc.shadow_ofs_x = 5
+rect_dsc.shadow_ofs_y = 5
+
+label_dsc = lv.draw_label_dsc_t()
+label_dsc.init()
+label_dsc.color = lv.palette_main(lv.PALETTE.YELLOW)
+
+cbuf = bytearray(_CANVAS_WIDTH * _CANVAS_HEIGHT * 4)
+
+canvas = lv.canvas(lv.scr_act())
+canvas.set_buffer(cbuf, _CANVAS_WIDTH, _CANVAS_HEIGHT, lv.img.CF.TRUE_COLOR)
+canvas.center()
+canvas.fill_bg(lv.palette_lighten(lv.PALETTE.GREY, 3), lv.OPA.COVER)
+
+canvas.draw_rect(70, 60, 100, 70, rect_dsc)
+canvas.draw_text(40, 20, 100, label_dsc, "Some text on text canvas")
+
+# Test the rotation. It requires another buffer where the original image is stored.
+# So copy the current image to buffer and rotate it to the canvas
+
+img = lv.img_dsc_t()
+img.data = cbuf[:]
+img.header.cf = lv.img.CF.TRUE_COLOR
+img.header.w = _CANVAS_WIDTH
+img.header.h = _CANVAS_HEIGHT
+
+canvas.fill_bg(lv.palette_lighten(lv.PALETTE.GREY, 3), lv.OPA.COVER)
+canvas.transform(img, 30, LV_IMG_ZOOM_NONE, 0, 0, _CANVAS_WIDTH // 2, _CANVAS_HEIGHT // 2, True)
diff --git a/lib/lvgl/examples/widgets/canvas/lv_example_canvas_2.c b/lib/lvgl/examples/widgets/canvas/lv_example_canvas_2.c
new file mode 100644
index 00000000..a857c668
--- /dev/null
+++ b/lib/lvgl/examples/widgets/canvas/lv_example_canvas_2.c
@@ -0,0 +1,44 @@
+#include "../../lv_examples.h"
+#if LV_USE_CANVAS && LV_BUILD_EXAMPLES
+
+#define CANVAS_WIDTH 50
+#define CANVAS_HEIGHT 50
+
+/**
+ * Create a transparent canvas with Chroma keying and indexed color format (palette).
+ */
+void lv_example_canvas_2(void)
+{
+ /*Create a button to better see the transparency*/
+ lv_btn_create(lv_scr_act());
+
+ /*Create a buffer for the canvas*/
+ static lv_color_t cbuf[LV_CANVAS_BUF_SIZE_INDEXED_1BIT(CANVAS_WIDTH, CANVAS_HEIGHT)];
+
+ /*Create a canvas and initialize its palette*/
+ lv_obj_t * canvas = lv_canvas_create(lv_scr_act());
+ lv_canvas_set_buffer(canvas, cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_IMG_CF_INDEXED_1BIT);
+ lv_canvas_set_palette(canvas, 0, LV_COLOR_CHROMA_KEY);
+ lv_canvas_set_palette(canvas, 1, lv_palette_main(LV_PALETTE_RED));
+
+ /*Create colors with the indices of the palette*/
+ lv_color_t c0;
+ lv_color_t c1;
+
+ c0.full = 0;
+ c1.full = 1;
+
+ /*Red background (There is no dedicated alpha channel in indexed images so LV_OPA_COVER is ignored)*/
+ lv_canvas_fill_bg(canvas, c1, LV_OPA_COVER);
+
+ /*Create hole on the canvas*/
+ uint32_t x;
+ uint32_t y;
+ for(y = 10; y < 30; y++) {
+ for(x = 5; x < 20; x++) {
+ lv_canvas_set_px_color(canvas, x, y, c0);
+ }
+ }
+
+}
+#endif
diff --git a/lib/lvgl/examples/widgets/canvas/lv_example_canvas_2.py b/lib/lvgl/examples/widgets/canvas/lv_example_canvas_2.py
new file mode 100644
index 00000000..faefc875
--- /dev/null
+++ b/lib/lvgl/examples/widgets/canvas/lv_example_canvas_2.py
@@ -0,0 +1,43 @@
+CANVAS_WIDTH = 50
+CANVAS_HEIGHT = 50
+LV_COLOR_CHROMA_KEY = lv.color_hex(0x00ff00)
+
+def LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h):
+ return int(((w / 8) + 1) * h)
+
+def LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h):
+ return LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h) + 4 * 2
+
+def LV_CANVAS_BUF_SIZE_INDEXED_1BIT(w, h):
+ return LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h)
+
+#
+# Create a transparent canvas with Chroma keying and indexed color format (palette).
+#
+
+# Create a button to better see the transparency
+btn=lv.btn(lv.scr_act())
+
+# Create a buffer for the canvas
+cbuf= bytearray(LV_CANVAS_BUF_SIZE_INDEXED_1BIT(CANVAS_WIDTH, CANVAS_HEIGHT))
+
+# Create a canvas and initialize its palette
+canvas = lv.canvas(lv.scr_act())
+canvas.set_buffer(cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, lv.img.CF.INDEXED_1BIT)
+canvas.set_palette(0, LV_COLOR_CHROMA_KEY)
+canvas.set_palette(1, lv.palette_main(lv.PALETTE.RED))
+
+# Create colors with the indices of the palette
+c0 = lv.color_t()
+c1 = lv.color_t()
+
+c0.full = 0
+c1.full = 1
+
+# Red background (There is no dedicated alpha channel in indexed images so LV_OPA_COVER is ignored)
+canvas.fill_bg(c1, lv.OPA.COVER)
+
+# Create hole on the canvas
+for y in range(10,30):
+ for x in range(5,20):
+ canvas.set_px(x, y, c0)
diff --git a/lib/lvgl/examples/widgets/chart/index.rst b/lib/lvgl/examples/widgets/chart/index.rst
new file mode 100644
index 00000000..d07f0969
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/index.rst
@@ -0,0 +1,49 @@
+
+Line Chart
+""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_1
+ :language: c
+
+
+Faded area line chart with custom division lines
+"""""""""""""""""""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_2
+ :language: c
+
+Axis ticks and labels with scrolling
+""""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_3
+ :language: c
+
+Show the value of the pressed points
+""""""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_4
+ :language: c
+
+Display 1000 data points with zooming and scrolling
+""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_5
+ :language: c
+
+Show cursor on the clicked point
+"""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_6
+ :language: c
+
+Scatter chart
+"""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_7
+ :language: c
+
+Stacked area chart
+"""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_8
+ :language:
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_1.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_1.c
new file mode 100644
index 00000000..a946e188
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_1.c
@@ -0,0 +1,44 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_BUILD_EXAMPLES
+
+void lv_example_chart_1(void)
+{
+ /*Create a chart*/
+ lv_obj_t * chart;
+ chart = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(chart, 200, 150);
+ lv_obj_center(chart);
+ lv_chart_set_type(chart, LV_CHART_TYPE_LINE); /*Show lines and points too*/
+
+ /*Add two data series*/
+ lv_chart_series_t * ser1 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
+ lv_chart_series_t * ser2 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_GREEN), LV_CHART_AXIS_SECONDARY_Y);
+
+ /*Set the next points on 'ser1'*/
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 30);
+ lv_chart_set_next_value(chart, ser1, 70);
+ lv_chart_set_next_value(chart, ser1, 90);
+
+ /*Directly set points on 'ser2'*/
+ ser2->y_points[0] = 90;
+ ser2->y_points[1] = 70;
+ ser2->y_points[2] = 65;
+ ser2->y_points[3] = 65;
+ ser2->y_points[4] = 65;
+ ser2->y_points[5] = 65;
+ ser2->y_points[6] = 65;
+ ser2->y_points[7] = 65;
+ ser2->y_points[8] = 65;
+ ser2->y_points[9] = 65;
+
+ lv_chart_refresh(chart); /*Required after direct set*/
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_1.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_1.py
new file mode 100644
index 00000000..ec7afc34
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_1.py
@@ -0,0 +1,26 @@
+# Create a chart
+chart = lv.chart(lv.scr_act())
+chart.set_size(200, 150)
+chart.center()
+chart.set_type(lv.chart.TYPE.LINE) # Show lines and points too
+
+# Add two data series
+ser1 = chart.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+ser2 = chart.add_series(lv.palette_main(lv.PALETTE.GREEN), lv.chart.AXIS.SECONDARY_Y)
+print(ser2)
+# Set next points on ser1
+chart.set_next_value(ser1,10)
+chart.set_next_value(ser1,10)
+chart.set_next_value(ser1,10)
+chart.set_next_value(ser1,10)
+chart.set_next_value(ser1,10)
+chart.set_next_value(ser1,10)
+chart.set_next_value(ser1,10)
+chart.set_next_value(ser1,30)
+chart.set_next_value(ser1,70)
+chart.set_next_value(ser1,90)
+
+# Directly set points on 'ser2'
+ser2.y_points = [90, 70, 65, 65, 65, 65, 65, 65, 65, 65]
+chart.refresh() # Required after direct set
+
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_2.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_2.c
new file mode 100644
index 00000000..a10f6f9e
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_2.c
@@ -0,0 +1,130 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_DRAW_COMPLEX && LV_BUILD_EXAMPLES
+
+static lv_obj_t * chart1;
+static lv_chart_series_t * ser1;
+static lv_chart_series_t * ser2;
+
+static void draw_event_cb(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+
+ /*Add the faded area before the lines are drawn*/
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+ if(dsc->part == LV_PART_ITEMS) {
+ if(!dsc->p1 || !dsc->p2) return;
+
+ /*Add a line mask that keeps the area below the line*/
+ lv_draw_mask_line_param_t line_mask_param;
+ lv_draw_mask_line_points_init(&line_mask_param, dsc->p1->x, dsc->p1->y, dsc->p2->x, dsc->p2->y,
+ LV_DRAW_MASK_LINE_SIDE_BOTTOM);
+ int16_t line_mask_id = lv_draw_mask_add(&line_mask_param, NULL);
+
+ /*Add a fade effect: transparent bottom covering top*/
+ lv_coord_t h = lv_obj_get_height(obj);
+ lv_draw_mask_fade_param_t fade_mask_param;
+ lv_draw_mask_fade_init(&fade_mask_param, &obj->coords, LV_OPA_COVER, obj->coords.y1 + h / 8, LV_OPA_TRANSP,
+ obj->coords.y2);
+ int16_t fade_mask_id = lv_draw_mask_add(&fade_mask_param, NULL);
+
+ /*Draw a rectangle that will be affected by the mask*/
+ lv_draw_rect_dsc_t draw_rect_dsc;
+ lv_draw_rect_dsc_init(&draw_rect_dsc);
+ draw_rect_dsc.bg_opa = LV_OPA_20;
+ draw_rect_dsc.bg_color = dsc->line_dsc->color;
+
+ lv_area_t a;
+ a.x1 = dsc->p1->x;
+ a.x2 = dsc->p2->x - 1;
+ a.y1 = LV_MIN(dsc->p1->y, dsc->p2->y);
+ a.y2 = obj->coords.y2;
+ lv_draw_rect(dsc->draw_ctx, &draw_rect_dsc, &a);
+
+ /*Remove the masks*/
+ lv_draw_mask_free_param(&line_mask_param);
+ lv_draw_mask_free_param(&fade_mask_param);
+ lv_draw_mask_remove_id(line_mask_id);
+ lv_draw_mask_remove_id(fade_mask_id);
+ }
+ /*Hook the division lines too*/
+ else if(dsc->part == LV_PART_MAIN) {
+ if(dsc->line_dsc == NULL || dsc->p1 == NULL || dsc->p2 == NULL) return;
+
+ /*Vertical line*/
+ if(dsc->p1->x == dsc->p2->x) {
+ dsc->line_dsc->color = lv_palette_lighten(LV_PALETTE_GREY, 1);
+ if(dsc->id == 3) {
+ dsc->line_dsc->width = 2;
+ dsc->line_dsc->dash_gap = 0;
+ dsc->line_dsc->dash_width = 0;
+ }
+ else {
+ dsc->line_dsc->width = 1;
+ dsc->line_dsc->dash_gap = 6;
+ dsc->line_dsc->dash_width = 6;
+ }
+ }
+ /*Horizontal line*/
+ else {
+ if(dsc->id == 2) {
+ dsc->line_dsc->width = 2;
+ dsc->line_dsc->dash_gap = 0;
+ dsc->line_dsc->dash_width = 0;
+ }
+ else {
+ dsc->line_dsc->width = 2;
+ dsc->line_dsc->dash_gap = 6;
+ dsc->line_dsc->dash_width = 6;
+ }
+
+ if(dsc->id == 1 || dsc->id == 3) {
+ dsc->line_dsc->color = lv_palette_main(LV_PALETTE_GREEN);
+ }
+ else {
+ dsc->line_dsc->color = lv_palette_lighten(LV_PALETTE_GREY, 1);
+ }
+ }
+ }
+}
+
+static void add_data(lv_timer_t * timer)
+{
+ LV_UNUSED(timer);
+ static uint32_t cnt = 0;
+ lv_chart_set_next_value(chart1, ser1, lv_rand(20, 90));
+
+ if(cnt % 4 == 0) lv_chart_set_next_value(chart1, ser2, lv_rand(40, 60));
+
+ cnt++;
+}
+
+/**
+ * Add a faded area effect to the line chart and make some division lines ticker
+ */
+void lv_example_chart_2(void)
+{
+ /*Create a chart1*/
+ chart1 = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(chart1, 200, 150);
+ lv_obj_center(chart1);
+ lv_chart_set_type(chart1, LV_CHART_TYPE_LINE); /*Show lines and points too*/
+
+ lv_chart_set_div_line_count(chart1, 5, 7);
+
+ lv_obj_add_event_cb(chart1, draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
+ lv_chart_set_update_mode(chart1, LV_CHART_UPDATE_MODE_CIRCULAR);
+
+ /*Add two data series*/
+ ser1 = lv_chart_add_series(chart1, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
+ ser2 = lv_chart_add_series(chart1, lv_palette_main(LV_PALETTE_BLUE), LV_CHART_AXIS_SECONDARY_Y);
+
+ uint32_t i;
+ for(i = 0; i < 10; i++) {
+ lv_chart_set_next_value(chart1, ser1, lv_rand(20, 90));
+ lv_chart_set_next_value(chart1, ser2, lv_rand(30, 70));
+ }
+
+ lv_timer_create(add_data, 200, NULL);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_2.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_2.py
new file mode 100644
index 00000000..ad2c8794
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_2.py
@@ -0,0 +1,76 @@
+def draw_event_cb(e):
+
+ obj = e.get_target()
+
+ # Add the faded area before the lines are drawn
+ dsc = lv.obj_draw_part_dsc_t.__cast__(e.get_param())
+ if dsc.part != lv.PART.ITEMS:
+ return
+ if not dsc.p1 or not dsc.p2:
+ return
+
+ # Add a line mask that keeps the area below the line
+ line_mask_param = lv.draw_mask_line_param_t()
+ line_mask_param.points_init(dsc.p1.x, dsc.p1.y, dsc.p2.x, dsc.p2.y, lv.DRAW_MASK_LINE_SIDE.BOTTOM)
+ # line_mask_id = line_mask_param.draw_mask_add(None)
+ line_mask_id = lv.draw_mask_add(line_mask_param, None)
+ # Add a fade effect: transparent bottom covering top
+ h = obj.get_height()
+ fade_mask_param = lv.draw_mask_fade_param_t()
+ coords = lv.area_t()
+ obj.get_coords(coords)
+ fade_mask_param.init(coords, lv.OPA.COVER, coords.y1 + h // 8, lv.OPA.TRANSP,coords.y2)
+ fade_mask_id = lv.draw_mask_add(fade_mask_param,None)
+
+ # Draw a rectangle that will be affected by the mask
+ draw_rect_dsc = lv.draw_rect_dsc_t()
+ draw_rect_dsc.init()
+ draw_rect_dsc.bg_opa = lv.OPA._20
+ draw_rect_dsc.bg_color = dsc.line_dsc.color
+
+ a = lv.area_t()
+ a.x1 = dsc.p1.x
+ a.x2 = dsc.p2.x - 1
+ a.y1 = min(dsc.p1.y, dsc.p2.y)
+ coords = lv.area_t()
+ obj.get_coords(coords)
+ a.y2 = coords.y2
+ dsc.draw_ctx.rect(draw_rect_dsc, a)
+
+ # Remove the masks
+ lv.draw_mask_remove_id(line_mask_id)
+ lv.draw_mask_remove_id(fade_mask_id)
+
+
+def add_data(timer):
+ # LV_UNUSED(timer);
+ cnt = 0
+ chart1.set_next_value(ser1, lv.rand(20, 90))
+
+ if cnt % 4 == 0:
+ chart1.set_next_value(ser2, lv.rand(40, 60))
+
+ cnt +=1
+
+#
+# Add a faded area effect to the line chart
+#
+
+# Create a chart1
+chart1 = lv.chart(lv.scr_act())
+chart1.set_size(200, 150)
+chart1.center()
+chart1.set_type(lv.chart.TYPE.LINE) # Show lines and points too
+
+chart1.add_event_cb(draw_event_cb, lv.EVENT.DRAW_PART_BEGIN, None)
+chart1.set_update_mode(lv.chart.UPDATE_MODE.CIRCULAR)
+
+# Add two data series
+ser1 = chart1.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+ser2 = chart1.add_series(lv.palette_main(lv.PALETTE.BLUE), lv.chart.AXIS.SECONDARY_Y)
+
+for i in range(10):
+ chart1.set_next_value(ser1, lv.rand(20, 90))
+ chart1.set_next_value(ser2, lv.rand(30, 70))
+
+timer = lv.timer_create(add_data, 200, None)
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_3.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_3.c
new file mode 100644
index 00000000..b5111502
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_3.c
@@ -0,0 +1,76 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_BUILD_EXAMPLES
+
+static void draw_event_cb(lv_event_t * e)
+{
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+ if(!lv_obj_draw_part_check_type(dsc, &lv_chart_class, LV_CHART_DRAW_PART_TICK_LABEL)) return;
+
+ if(dsc->id == LV_CHART_AXIS_PRIMARY_X && dsc->text) {
+ const char * month[] = {"Jan", "Febr", "March", "Apr", "May", "Jun", "July", "Aug", "Sept", "Oct", "Nov", "Dec"};
+ lv_snprintf(dsc->text, dsc->text_length, "%s", month[dsc->value]);
+ }
+}
+
+/**
+ * Add ticks and labels to the axis and demonstrate scrolling
+ */
+void lv_example_chart_3(void)
+{
+ /*Create a chart*/
+ lv_obj_t * chart;
+ chart = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(chart, 200, 150);
+ lv_obj_center(chart);
+ lv_chart_set_type(chart, LV_CHART_TYPE_BAR);
+ lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 100);
+ lv_chart_set_range(chart, LV_CHART_AXIS_SECONDARY_Y, 0, 400);
+ lv_chart_set_point_count(chart, 12);
+ lv_obj_add_event_cb(chart, draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
+
+ /*Add ticks and label to every axis*/
+ lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_X, 10, 5, 12, 3, true, 40);
+ lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_Y, 10, 5, 6, 2, true, 50);
+ lv_chart_set_axis_tick(chart, LV_CHART_AXIS_SECONDARY_Y, 10, 5, 3, 4, true, 50);
+
+ /*Zoom in a little in X*/
+ lv_chart_set_zoom_x(chart, 800);
+
+ /*Add two data series*/
+ lv_chart_series_t * ser1 = lv_chart_add_series(chart, lv_palette_lighten(LV_PALETTE_GREEN, 2), LV_CHART_AXIS_PRIMARY_Y);
+ lv_chart_series_t * ser2 = lv_chart_add_series(chart, lv_palette_darken(LV_PALETTE_GREEN, 2),
+ LV_CHART_AXIS_SECONDARY_Y);
+
+ /*Set the next points on 'ser1'*/
+ lv_chart_set_next_value(chart, ser1, 31);
+ lv_chart_set_next_value(chart, ser1, 66);
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 89);
+ lv_chart_set_next_value(chart, ser1, 63);
+ lv_chart_set_next_value(chart, ser1, 56);
+ lv_chart_set_next_value(chart, ser1, 32);
+ lv_chart_set_next_value(chart, ser1, 35);
+ lv_chart_set_next_value(chart, ser1, 57);
+ lv_chart_set_next_value(chart, ser1, 85);
+ lv_chart_set_next_value(chart, ser1, 22);
+ lv_chart_set_next_value(chart, ser1, 58);
+
+ lv_coord_t * ser2_array = lv_chart_get_y_array(chart, ser2);
+ /*Directly set points on 'ser2'*/
+ ser2_array[0] = 92;
+ ser2_array[1] = 71;
+ ser2_array[2] = 61;
+ ser2_array[3] = 15;
+ ser2_array[4] = 21;
+ ser2_array[5] = 35;
+ ser2_array[6] = 35;
+ ser2_array[7] = 58;
+ ser2_array[8] = 31;
+ ser2_array[9] = 53;
+ ser2_array[10] = 33;
+ ser2_array[11] = 73;
+
+ lv_chart_refresh(chart); /*Required after direct set*/
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_3.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_3.py
new file mode 100644
index 00000000..0afe6fe1
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_3.py
@@ -0,0 +1,52 @@
+def draw_event_cb(e):
+
+ dsc = lv.obj_draw_part_dsc_t.__cast__(e.get_param())
+ if dsc.part == lv.PART.TICKS and dsc.id == lv.chart.AXIS.PRIMARY_X:
+ month = ["Jan", "Febr", "March", "Apr", "May", "Jun", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]
+ # dsc.text is defined char text[16], I must therefore convert the Python string to a byte_array
+ dsc.text = bytes(month[dsc.value],"ascii")
+#
+# Add ticks and labels to the axis and demonstrate scrolling
+#
+
+# Create a chart
+chart = lv.chart(lv.scr_act())
+chart.set_size(200, 150)
+chart.center()
+chart.set_type(lv.chart.TYPE.BAR)
+chart.set_range(lv.chart.AXIS.PRIMARY_Y, 0, 100)
+chart.set_range(lv.chart.AXIS.SECONDARY_Y, 0, 400)
+chart.set_point_count(12)
+chart.add_event_cb(draw_event_cb, lv.EVENT.DRAW_PART_BEGIN, None)
+
+# Add ticks and label to every axis
+chart.set_axis_tick(lv.chart.AXIS.PRIMARY_X, 10, 5, 12, 3, True, 40)
+chart.set_axis_tick(lv.chart.AXIS.PRIMARY_Y, 10, 5, 6, 2, True, 50)
+chart.set_axis_tick(lv.chart.AXIS.SECONDARY_Y, 10, 5, 3, 4,True, 50)
+
+# Zoom in a little in X
+chart.set_zoom_x(800)
+
+# Add two data series
+ser1 = lv.chart.add_series(chart, lv.palette_lighten(lv.PALETTE.GREEN, 2), lv.chart.AXIS.PRIMARY_Y)
+ser2 = lv.chart.add_series(chart, lv.palette_darken(lv.PALETTE.GREEN, 2), lv.chart.AXIS.SECONDARY_Y)
+
+# Set the next points on 'ser1'
+chart.set_next_value(ser1, 31)
+chart.set_next_value(ser1, 66)
+chart.set_next_value(ser1, 10)
+chart.set_next_value(ser1, 89)
+chart.set_next_value(ser1, 63)
+chart.set_next_value(ser1, 56)
+chart.set_next_value(ser1, 32)
+chart.set_next_value(ser1, 35)
+chart.set_next_value(ser1, 57)
+chart.set_next_value(ser1, 85)
+chart.set_next_value(ser1, 22)
+chart.set_next_value(ser1, 58)
+
+# Directly set points on 'ser2'
+ser2.y_points = [92,71,61,15,21,35,35,58,31,53,33,73]
+
+chart.refresh() # Required after direct set
+
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_4.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_4.c
new file mode 100644
index 00000000..8508ef18
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_4.c
@@ -0,0 +1,86 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_BUILD_EXAMPLES
+
+
+static void event_cb(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * chart = lv_event_get_target(e);
+
+ if(code == LV_EVENT_VALUE_CHANGED) {
+ lv_obj_invalidate(chart);
+ }
+ if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
+ lv_coord_t * s = lv_event_get_param(e);
+ *s = LV_MAX(*s, 20);
+ }
+ else if(code == LV_EVENT_DRAW_POST_END) {
+ int32_t id = lv_chart_get_pressed_point(chart);
+ if(id == LV_CHART_POINT_NONE) return;
+
+ LV_LOG_USER("Selected point %d", (int)id);
+
+ lv_chart_series_t * ser = lv_chart_get_series_next(chart, NULL);
+ while(ser) {
+ lv_point_t p;
+ lv_chart_get_point_pos_by_id(chart, ser, id, &p);
+
+ lv_coord_t * y_array = lv_chart_get_y_array(chart, ser);
+ lv_coord_t value = y_array[id];
+
+ char buf[16];
+ lv_snprintf(buf, sizeof(buf), LV_SYMBOL_DUMMY"$%d", value);
+
+ lv_draw_rect_dsc_t draw_rect_dsc;
+ lv_draw_rect_dsc_init(&draw_rect_dsc);
+ draw_rect_dsc.bg_color = lv_color_black();
+ draw_rect_dsc.bg_opa = LV_OPA_50;
+ draw_rect_dsc.radius = 3;
+ draw_rect_dsc.bg_img_src = buf;
+ draw_rect_dsc.bg_img_recolor = lv_color_white();
+
+ lv_area_t a;
+ a.x1 = chart->coords.x1 + p.x - 20;
+ a.x2 = chart->coords.x1 + p.x + 20;
+ a.y1 = chart->coords.y1 + p.y - 30;
+ a.y2 = chart->coords.y1 + p.y - 10;
+
+ lv_draw_ctx_t * draw_ctx = lv_event_get_draw_ctx(e);
+ lv_draw_rect(draw_ctx, &draw_rect_dsc, &a);
+
+ ser = lv_chart_get_series_next(chart, ser);
+ }
+ }
+ else if(code == LV_EVENT_RELEASED) {
+ lv_obj_invalidate(chart);
+ }
+}
+
+/**
+ * Show the value of the pressed points
+ */
+void lv_example_chart_4(void)
+{
+ /*Create a chart*/
+ lv_obj_t * chart;
+ chart = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(chart, 200, 150);
+ lv_obj_center(chart);
+
+ lv_obj_add_event_cb(chart, event_cb, LV_EVENT_ALL, NULL);
+ lv_obj_refresh_ext_draw_size(chart);
+
+ /*Zoom in a little in X*/
+ lv_chart_set_zoom_x(chart, 800);
+
+ /*Add two data series*/
+ lv_chart_series_t * ser1 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
+ lv_chart_series_t * ser2 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_GREEN), LV_CHART_AXIS_PRIMARY_Y);
+ uint32_t i;
+ for(i = 0; i < 10; i++) {
+ lv_chart_set_next_value(chart, ser1, lv_rand(60, 90));
+ lv_chart_set_next_value(chart, ser2, lv_rand(10, 40));
+ }
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_4.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_4.py
new file mode 100644
index 00000000..3b8d0633
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_4.py
@@ -0,0 +1,73 @@
+def event_cb(e):
+ code = e.get_code()
+ chart = e.get_target()
+
+ if code == lv.EVENT.VALUE_CHANGED:
+ chart.invalidate()
+
+ if code == lv.EVENT.REFR_EXT_DRAW_SIZE:
+ e.set_ext_draw_size(20)
+
+ elif code == lv.EVENT.DRAW_POST_END:
+ id = lv.chart.get_pressed_point(chart)
+ if id == lv.CHART_POINT.NONE:
+ return
+ # print("Selected point ", id)
+ for i in range(len(series)):
+ p = lv.point_t()
+ chart.get_point_pos_by_id(series[i], id, p)
+ value = series_points[i][id]
+ buf = lv.SYMBOL.DUMMY + "$" + str(value)
+
+ draw_rect_dsc = lv.draw_rect_dsc_t()
+ draw_rect_dsc.init()
+ draw_rect_dsc.bg_color = lv.color_black()
+ draw_rect_dsc.bg_opa = lv.OPA._50
+ draw_rect_dsc.radius = 3
+ draw_rect_dsc.bg_img_src = buf
+ draw_rect_dsc.bg_img_recolor = lv.color_white()
+
+ a = lv.area_t()
+ coords = lv.area_t()
+ chart.get_coords(coords)
+ a.x1 = coords.x1 + p.x - 20
+ a.x2 = coords.x1 + p.x + 20
+ a.y1 = coords.y1 + p.y - 30
+ a.y2 = coords.y1 + p.y - 10
+
+ clip_area = lv.area_t.__cast__(e.get_param())
+ lv.draw_rect(a, clip_area, draw_rect_dsc)
+
+ elif code == lv.EVENT.RELEASED:
+ chart.invalidate()
+
+#
+# Add ticks and labels to the axis and demonstrate scrolling
+#
+
+# Create a chart
+chart = lv.chart(lv.scr_act())
+chart.set_size(200, 150)
+chart.center()
+
+chart.add_event_cb(event_cb, lv.EVENT.ALL, None)
+chart.refresh_ext_draw_size()
+
+# Zoom in a little in X
+chart.set_zoom_x(800)
+
+# Add two data series
+ser1 = chart.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+ser2 = chart.add_series(lv.palette_main(lv.PALETTE.GREEN), lv.chart.AXIS.PRIMARY_Y)
+
+ser1_p = []
+ser2_p = []
+for i in range(10):
+ ser1_p.append(lv.rand(60,90))
+ ser2_p.append(lv.rand(10,40))
+ser1.y_points = ser1_p
+ser2.y_points = ser2_p
+
+series = [ser1,ser2]
+series_points=[ser1_p,ser2_p]
+
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_5.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_5.c
new file mode 100644
index 00000000..c175e37c
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_5.c
@@ -0,0 +1,99 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_USE_SLIDER && LV_BUILD_EXAMPLES
+
+static lv_obj_t * chart;
+/* Source: https://github.com/ankur219/ECG-Arrhythmia-classification/blob/642230149583adfae1e4bd26c6f0e1fd8af2be0e/sample.csv*/
+static const lv_coord_t ecg_sample[] = {
+ -2, 2, 0, -15, -39, -63, -71, -68, -67, -69, -84, -95, -104, -107, -108, -107, -107, -107, -107, -114, -118, -117,
+ -112, -100, -89, -83, -71, -64, -58, -58, -62, -62, -58, -51, -46, -39, -27, -10, 4, 7, 1, -3, 0, 14, 24, 30, 25, 19,
+ 13, 7, 12, 15, 18, 21, 13, 6, 9, 8, 17, 19, 13, 11, 11, 11, 23, 30, 37, 34, 25, 14, 15, 19, 28, 31, 26, 23, 25, 31,
+ 39, 37, 37, 34, 30, 32, 22, 29, 31, 33, 37, 23, 13, 7, 2, 4, -2, 2, 11, 22, 33, 19, -1, -27, -55, -67, -72, -71, -63,
+ -49, -18, 35, 113, 230, 369, 525, 651, 722, 730, 667, 563, 454, 357, 305, 288, 274, 255, 212, 173, 143, 117, 82, 39,
+ -13, -53, -78, -91, -101, -113, -124, -131, -131, -131, -129, -128, -129, -125, -123, -123, -129, -139, -148, -153,
+ -159, -166, -183, -205, -227, -243, -248, -246, -254, -280, -327, -381, -429, -473, -517, -556, -592, -612, -620,
+ -620, -614, -604, -591, -574, -540, -497, -441, -389, -358, -336, -313, -284, -222, -167, -114, -70, -47, -28, -4, 12,
+ 38, 52, 58, 56, 56, 57, 68, 77, 86, 86, 80, 69, 67, 70, 82, 85, 89, 90, 89, 89, 88, 91, 96, 97, 91, 83, 78, 82, 88, 95,
+ 96, 105, 106, 110, 102, 100, 96, 98, 97, 101, 98, 99, 100, 107, 113, 119, 115, 110, 96, 85, 73, 64, 69, 76, 79,
+ 78, 75, 85, 100, 114, 113, 105, 96, 84, 74, 66, 60, 75, 85, 89, 83, 67, 61, 67, 73, 79, 74, 63, 57, 56, 58, 61, 55,
+ 48, 45, 46, 55, 62, 55, 49, 43, 50, 59, 63, 57, 40, 31, 23, 25, 27, 31, 35, 34, 30, 36, 34, 42, 38, 36, 40, 46, 50,
+ 47, 32, 30, 32, 52, 67, 73, 71, 63, 54, 53, 45, 41, 28, 13, 3, 1, 4, 4, -8, -23, -32, -31, -19, -5, 3, 9, 13, 19,
+ 24, 27, 29, 25, 22, 26, 32, 42, 51, 56, 60, 57, 55, 53, 53, 54, 59, 54, 49, 26, -3, -11, -20, -47, -100, -194, -236,
+ -212, -123, 8, 103, 142, 147, 120, 105, 98, 93, 81, 61, 40, 26, 28, 30, 30, 27, 19, 17, 21, 20, 19, 19, 22, 36, 40,
+ 35, 20, 7, 1, 10, 18, 27, 22, 6, -4, -2, 3, 6, -2, -13, -14, -10, -2, 3, 2, -1, -5, -10, -19, -32, -42, -55, -60,
+ -68, -77, -86, -101, -110, -117, -115, -104, -92, -84, -85, -84, -73, -65, -52, -50, -45, -35, -20, -3, 12, 20, 25,
+ 26, 28, 28, 30, 28, 25, 28, 33, 42, 42, 36, 23, 9, 0, 1, -4, 1, -4, -4, 1, 5, 9, 9, -3, -1, -18, -50, -108, -190,
+ -272, -340, -408, -446, -537, -643, -777, -894, -920, -853, -697, -461, -251, -60, 58, 103, 129, 139, 155, 170, 173,
+ 178, 185, 190, 193, 200, 208, 215, 225, 224, 232, 234, 240, 240, 236, 229, 226, 224, 232, 233, 232, 224, 219, 219,
+ 223, 231, 226, 223, 219, 218, 223, 223, 223, 233, 245, 268, 286, 296, 295, 283, 271, 263, 252, 243, 226, 210, 197,
+ 186, 171, 152, 133, 117, 114, 110, 107, 96, 80, 63, 48, 40, 38, 34, 28, 15, 2, -7, -11, -14, -18, -29, -37, -44, -50,
+ -58, -63, -61, -52, -50, -48, -61, -59, -58, -54, -47, -52, -62, -61, -64, -54, -52, -59, -69, -76, -76, -69, -67,
+ -74, -78, -81, -80, -73, -65, -57, -53, -51, -47, -35, -27, -22, -22, -24, -21, -17, -13, -10, -11, -13, -20, -20,
+ -12, -2, 7, -1, -12, -16, -13, -2, 2, -4, -5, -2, 9, 19, 19, 14, 11, 13, 19, 21, 20, 18, 19, 19, 19, 16, 15, 13, 14,
+ 9, 3, -5, -9, -5, -3, -2, -3, -3, 2, 8, 9, 9, 5, 6, 8, 8, 7, 4, 3, 4, 5, 3, 5, 5, 13, 13, 12, 10, 10, 15, 22, 17,
+ 14, 7, 10, 15, 16, 11, 12, 10, 13, 9, -2, -4, -2, 7, 16, 16, 17, 16, 7, -1, -16, -18, -16, -9, -4, -5, -10, -9, -8,
+ -3, -4, -10, -19, -20, -16, -9, -9, -23, -40, -48, -43, -33, -19, -21, -26, -31, -33, -19, 0, 17, 24, 9, -17, -47,
+ -63, -67, -59, -52, -51, -50, -49, -42, -26, -21, -15, -20, -23, -22, -19, -12, -8, 5, 18, 27, 32, 26, 25, 26, 22,
+ 23, 17, 14, 17, 21, 25, 2, -45, -121, -196, -226, -200, -118, -9, 73, 126, 131, 114, 87, 60, 42, 29, 26, 34, 35, 34,
+ 25, 12, 9, 7, 3, 2, -8, -11, 2, 23, 38, 41, 23, 9, 10, 13, 16, 8, -8, -17, -23, -26, -25, -21, -15, -10, -13, -13,
+ -19, -22, -29, -40, -48, -48, -54, -55, -66, -82, -85, -90, -92, -98, -114, -119, -124, -129, -132, -146, -146, -138,
+ -124, -99, -85, -72, -65, -65, -65, -66, -63, -64, -64, -58, -46, -26, -9, 2, 2, 4, 0, 1, 4, 3, 10, 11, 10, 2, -4,
+ 0, 10, 18, 20, 6, 2, -9, -7, -3, -3, -2, -7, -12, -5, 5, 24, 36, 31, 25, 6, 3, 7, 12, 17, 11, 0, -6, -9, -8, -7, -5,
+ -6, -2, -2, -6, -2, 2, 14, 24, 22, 15, 8, 4, 6, 7, 12, 16, 25, 20, 7, -16, -41, -60, -67, -65, -54, -35, -11, 30,
+ 84, 175, 302, 455, 603, 707, 743, 714, 625, 519, 414, 337, 300, 281, 263, 239, 197, 163, 136, 109, 77, 34, -18, -50,
+ -66, -74, -79, -92, -107, -117, -127, -129, -135, -139, -141, -155, -159, -167, -171, -169, -174, -175, -178, -191,
+ -202, -223, -235, -243, -237, -240, -256, -298, -345, -393, -432, -475, -518, -565, -596, -619, -623, -623, -614,
+ -599, -583, -559, -524, -477, -425, -383, -357, -331, -301, -252, -198, -143, -96, -57, -29, -8, 10, 31, 45, 60, 65,
+ 70, 74, 76, 79, 82, 79, 75, 62,
+ };
+
+static void slider_x_event_cb(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+ int32_t v = lv_slider_get_value(obj);
+ lv_chart_set_zoom_x(chart, v);
+}
+
+static void slider_y_event_cb(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+ int32_t v = lv_slider_get_value(obj);
+ lv_chart_set_zoom_y(chart, v);
+}
+
+/**
+ * Display 1000 data points with zooming and scrolling.
+ * See how the chart changes drawing mode (draw only vertical lines) when
+ * the points get too crowded.
+ */
+void lv_example_chart_5(void)
+{
+ /*Create a chart*/
+ chart = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(chart, 200, 150);
+ lv_obj_align(chart, LV_ALIGN_CENTER, -30, -30);
+ lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, -1000, 1000);
+
+ /*Do not display points on the data*/
+ lv_obj_set_style_size(chart, 0, LV_PART_INDICATOR);
+
+ lv_chart_series_t * ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
+
+ uint32_t pcnt = sizeof(ecg_sample) / sizeof(ecg_sample[0]);
+ lv_chart_set_point_count(chart, pcnt);
+ lv_chart_set_ext_y_array(chart, ser, (lv_coord_t *)ecg_sample);
+
+ lv_obj_t * slider;
+ slider = lv_slider_create(lv_scr_act());
+ lv_slider_set_range(slider, LV_IMG_ZOOM_NONE, LV_IMG_ZOOM_NONE * 10);
+ lv_obj_add_event_cb(slider, slider_x_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
+ lv_obj_set_size(slider, 200, 10);
+ lv_obj_align_to(slider, chart, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);
+
+ slider = lv_slider_create(lv_scr_act());
+ lv_slider_set_range(slider, LV_IMG_ZOOM_NONE, LV_IMG_ZOOM_NONE * 10);
+ lv_obj_add_event_cb(slider, slider_y_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
+ lv_obj_set_size(slider, 10, 150);
+ lv_obj_align_to(slider, chart, LV_ALIGN_OUT_RIGHT_MID, 20, 0);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_5.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_5.py
new file mode 100644
index 00000000..f0d58323
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_5.py
@@ -0,0 +1,89 @@
+# Source: https://github.com/ankur219/ECG-Arrhythmia-classification/blob/642230149583adfae1e4bd26c6f0e1fd8af2be0e/sample.csv
+ecg_sample = [
+ -2, 2, 0, -15, -39, -63, -71, -68, -67, -69, -84, -95, -104, -107, -108, -107, -107, -107, -107, -114, -118, -117,
+ -112, -100, -89, -83, -71, -64, -58, -58, -62, -62, -58, -51, -46, -39, -27, -10, 4, 7, 1, -3, 0, 14, 24, 30, 25, 19,
+ 13, 7, 12, 15, 18, 21, 13, 6, 9, 8, 17, 19, 13, 11, 11, 11, 23, 30, 37, 34, 25, 14, 15, 19, 28, 31, 26, 23, 25, 31,
+ 39, 37, 37, 34, 30, 32, 22, 29, 31, 33, 37, 23, 13, 7, 2, 4, -2, 2, 11, 22, 33, 19, -1, -27, -55, -67, -72, -71, -63,
+ -49, -18, 35, 113, 230, 369, 525, 651, 722, 730, 667, 563, 454, 357, 305, 288, 274, 255, 212, 173, 143, 117, 82, 39,
+ -13, -53, -78, -91, -101, -113, -124, -131, -131, -131, -129, -128, -129, -125, -123, -123, -129, -139, -148, -153,
+ -159, -166, -183, -205, -227, -243, -248, -246, -254, -280, -327, -381, -429, -473, -517, -556, -592, -612, -620,
+ -620, -614, -604, -591, -574, -540, -497, -441, -389, -358, -336, -313, -284, -222, -167, -114, -70, -47, -28, -4, 12,
+ 38, 52, 58, 56, 56, 57, 68, 77, 86, 86, 80, 69, 67, 70, 82, 85, 89, 90, 89, 89, 88, 91, 96, 97, 91, 83, 78, 82, 88, 95,
+ 96, 105, 106, 110, 102, 100, 96, 98, 97, 101, 98, 99, 100, 107, 113, 119, 115, 110, 96, 85, 73, 64, 69, 76, 79,
+ 78, 75, 85, 100, 114, 113, 105, 96, 84, 74, 66, 60, 75, 85, 89, 83, 67, 61, 67, 73, 79, 74, 63, 57, 56, 58, 61, 55,
+ 48, 45, 46, 55, 62, 55, 49, 43, 50, 59, 63, 57, 40, 31, 23, 25, 27, 31, 35, 34, 30, 36, 34, 42, 38, 36, 40, 46, 50,
+ 47, 32, 30, 32, 52, 67, 73, 71, 63, 54, 53, 45, 41, 28, 13, 3, 1, 4, 4, -8, -23, -32, -31, -19, -5, 3, 9, 13, 19,
+ 24, 27, 29, 25, 22, 26, 32, 42, 51, 56, 60, 57, 55, 53, 53, 54, 59, 54, 49, 26, -3, -11, -20, -47, -100, -194, -236,
+ -212, -123, 8, 103, 142, 147, 120, 105, 98, 93, 81, 61, 40, 26, 28, 30, 30, 27, 19, 17, 21, 20, 19, 19, 22, 36, 40,
+ 35, 20, 7, 1, 10, 18, 27, 22, 6, -4, -2, 3, 6, -2, -13, -14, -10, -2, 3, 2, -1, -5, -10, -19, -32, -42, -55, -60,
+ -68, -77, -86, -101, -110, -117, -115, -104, -92, -84, -85, -84, -73, -65, -52, -50, -45, -35, -20, -3, 12, 20, 25,
+ 26, 28, 28, 30, 28, 25, 28, 33, 42, 42, 36, 23, 9, 0, 1, -4, 1, -4, -4, 1, 5, 9, 9, -3, -1, -18, -50, -108, -190,
+ -272, -340, -408, -446, -537, -643, -777, -894, -920, -853, -697, -461, -251, -60, 58, 103, 129, 139, 155, 170, 173,
+ 178, 185, 190, 193, 200, 208, 215, 225, 224, 232, 234, 240, 240, 236, 229, 226, 224, 232, 233, 232, 224, 219, 219,
+ 223, 231, 226, 223, 219, 218, 223, 223, 223, 233, 245, 268, 286, 296, 295, 283, 271, 263, 252, 243, 226, 210, 197,
+ 186, 171, 152, 133, 117, 114, 110, 107, 96, 80, 63, 48, 40, 38, 34, 28, 15, 2, -7, -11, -14, -18, -29, -37, -44, -50,
+ -58, -63, -61, -52, -50, -48, -61, -59, -58, -54, -47, -52, -62, -61, -64, -54, -52, -59, -69, -76, -76, -69, -67,
+ -74, -78, -81, -80, -73, -65, -57, -53, -51, -47, -35, -27, -22, -22, -24, -21, -17, -13, -10, -11, -13, -20, -20,
+ -12, -2, 7, -1, -12, -16, -13, -2, 2, -4, -5, -2, 9, 19, 19, 14, 11, 13, 19, 21, 20, 18, 19, 19, 19, 16, 15, 13, 14,
+ 9, 3, -5, -9, -5, -3, -2, -3, -3, 2, 8, 9, 9, 5, 6, 8, 8, 7, 4, 3, 4, 5, 3, 5, 5, 13, 13, 12, 10, 10, 15, 22, 17,
+ 14, 7, 10, 15, 16, 11, 12, 10, 13, 9, -2, -4, -2, 7, 16, 16, 17, 16, 7, -1, -16, -18, -16, -9, -4, -5, -10, -9, -8,
+ -3, -4, -10, -19, -20, -16, -9, -9, -23, -40, -48, -43, -33, -19, -21, -26, -31, -33, -19, 0, 17, 24, 9, -17, -47,
+ -63, -67, -59, -52, -51, -50, -49, -42, -26, -21, -15, -20, -23, -22, -19, -12, -8, 5, 18, 27, 32, 26, 25, 26, 22,
+ 23, 17, 14, 17, 21, 25, 2, -45, -121, -196, -226, -200, -118, -9, 73, 126, 131, 114, 87, 60, 42, 29, 26, 34, 35, 34,
+ 25, 12, 9, 7, 3, 2, -8, -11, 2, 23, 38, 41, 23, 9, 10, 13, 16, 8, -8, -17, -23, -26, -25, -21, -15, -10, -13, -13,
+ -19, -22, -29, -40, -48, -48, -54, -55, -66, -82, -85, -90, -92, -98, -114, -119, -124, -129, -132, -146, -146, -138,
+ -124, -99, -85, -72, -65, -65, -65, -66, -63, -64, -64, -58, -46, -26, -9, 2, 2, 4, 0, 1, 4, 3, 10, 11, 10, 2, -4,
+ 0, 10, 18, 20, 6, 2, -9, -7, -3, -3, -2, -7, -12, -5, 5, 24, 36, 31, 25, 6, 3, 7, 12, 17, 11, 0, -6, -9, -8, -7, -5,
+ -6, -2, -2, -6, -2, 2, 14, 24, 22, 15, 8, 4, 6, 7, 12, 16, 25, 20, 7, -16, -41, -60, -67, -65, -54, -35, -11, 30,
+ 84, 175, 302, 455, 603, 707, 743, 714, 625, 519, 414, 337, 300, 281, 263, 239, 197, 163, 136, 109, 77, 34, -18, -50,
+ -66, -74, -79, -92, -107, -117, -127, -129, -135, -139, -141, -155, -159, -167, -171, -169, -174, -175, -178, -191,
+ -202, -223, -235, -243, -237, -240, -256, -298, -345, -393, -432, -475, -518, -565, -596, -619, -623, -623, -614,
+ -599, -583, -559, -524, -477, -425, -383, -357, -331, -301, -252, -198, -143, -96, -57, -29, -8, 10, 31, 45, 60, 65,
+ 70, 74, 76, 79, 82, 79, 75, 62,
+]
+
+def slider_x_event_cb(e):
+
+ slider = e.get_target()
+ v = slider.get_value()
+ chart.set_zoom_x(v)
+
+def slider_y_event_cb(e):
+
+ slider = e.get_target()
+ v = slider.get_value()
+ chart.set_zoom_y(v)
+
+
+#
+# Display 1000 data points with zooming and scrolling.
+# See how the chart changes drawing mode (draw only vertical lines) when
+# the points get too crowded.
+
+# Create a chart
+chart = lv.chart(lv.scr_act())
+chart.set_size(200, 150)
+chart.align(lv.ALIGN.CENTER, -30, -30)
+chart.set_range(lv.chart.AXIS.PRIMARY_Y, -1000, 1000)
+
+# Do not display points on the data
+chart.set_style_size(0, lv.PART.INDICATOR)
+
+ser = chart.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+
+pcnt = len(ecg_sample)
+chart.set_point_count(pcnt)
+chart.set_ext_y_array(ser, ecg_sample)
+
+slider = lv.slider(lv.scr_act())
+slider.set_range(lv.IMG_ZOOM.NONE, lv.IMG_ZOOM.NONE * 10)
+slider.add_event_cb(slider_x_event_cb, lv.EVENT.VALUE_CHANGED, None)
+slider.set_size(200,10)
+slider.align_to(chart, lv.ALIGN.OUT_BOTTOM_MID, 0, 20)
+
+slider = lv.slider(lv.scr_act())
+slider.set_range(lv.IMG_ZOOM.NONE, lv.IMG_ZOOM.NONE * 10)
+slider.add_event_cb(slider_y_event_cb, lv.EVENT.VALUE_CHANGED, None)
+slider.set_size(10, 150)
+slider.align_to(chart, lv.ALIGN.OUT_RIGHT_MID, 20, 0)
+
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_6.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_6.c
new file mode 100644
index 00000000..463ab670
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_6.c
@@ -0,0 +1,87 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_BUILD_EXAMPLES
+
+static lv_obj_t * chart;
+static lv_chart_series_t * ser;
+static lv_chart_cursor_t * cursor;
+
+static void event_cb(lv_event_t * e)
+{
+ static int32_t last_id = -1;
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+
+ if(code == LV_EVENT_VALUE_CHANGED) {
+ last_id = lv_chart_get_pressed_point(obj);
+ if(last_id != LV_CHART_POINT_NONE) {
+ lv_chart_set_cursor_point(obj, cursor, NULL, last_id);
+ }
+ }
+ else if(code == LV_EVENT_DRAW_PART_END) {
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+ if(!lv_obj_draw_part_check_type(dsc, &lv_chart_class, LV_CHART_DRAW_PART_CURSOR)) return;
+ if(dsc->p1 == NULL || dsc->p2 == NULL || dsc->p1->y != dsc->p2->y || last_id < 0) return;
+
+ lv_coord_t * data_array = lv_chart_get_y_array(chart, ser);
+ lv_coord_t v = data_array[last_id];
+ char buf[16];
+ lv_snprintf(buf, sizeof(buf), "%d", v);
+
+ lv_point_t size;
+ lv_txt_get_size(&size, buf, LV_FONT_DEFAULT, 0, 0, LV_COORD_MAX, LV_TEXT_FLAG_NONE);
+
+ lv_area_t a;
+ a.y2 = dsc->p1->y - 5;
+ a.y1 = a.y2 - size.y - 10;
+ a.x1 = dsc->p1->x + 10;
+ a.x2 = a.x1 + size.x + 10;
+
+ lv_draw_rect_dsc_t draw_rect_dsc;
+ lv_draw_rect_dsc_init(&draw_rect_dsc);
+ draw_rect_dsc.bg_color = lv_palette_main(LV_PALETTE_BLUE);
+ draw_rect_dsc.radius = 3;
+
+ lv_draw_rect(dsc->draw_ctx, &draw_rect_dsc, &a);
+
+ lv_draw_label_dsc_t draw_label_dsc;
+ lv_draw_label_dsc_init(&draw_label_dsc);
+ draw_label_dsc.color = lv_color_white();
+ a.x1 += 5;
+ a.x2 -= 5;
+ a.y1 += 5;
+ a.y2 -= 5;
+ lv_draw_label(dsc->draw_ctx, &draw_label_dsc, &a, buf, NULL);
+ }
+}
+
+/**
+ * Show cursor on the clicked point
+ */
+void lv_example_chart_6(void)
+{
+ chart = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(chart, 200, 150);
+ lv_obj_align(chart, LV_ALIGN_CENTER, 0, -10);
+
+ lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_Y, 10, 5, 6, 5, true, 40);
+ lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_X, 10, 5, 10, 1, true, 30);
+
+ lv_obj_add_event_cb(chart, event_cb, LV_EVENT_ALL, NULL);
+ lv_obj_refresh_ext_draw_size(chart);
+
+ cursor = lv_chart_add_cursor(chart, lv_palette_main(LV_PALETTE_BLUE), LV_DIR_LEFT | LV_DIR_BOTTOM);
+
+ ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
+ uint32_t i;
+ for(i = 0; i < 10; i++) {
+ lv_chart_set_next_value(chart, ser, lv_rand(10, 90));
+ }
+
+ lv_chart_set_zoom_x(chart, 500);
+
+ lv_obj_t * label = lv_label_create(lv_scr_act());
+ lv_label_set_text(label, "Click on a point");
+ lv_obj_align_to(label, chart, LV_ALIGN_OUT_TOP_MID, 0, -5);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_6.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_6.py
new file mode 100644
index 00000000..acc4e11c
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_6.py
@@ -0,0 +1,88 @@
+class ExampleChart_6():
+
+ def __init__(self):
+ self.last_id = -1
+ #
+ # Show cursor on the clicked point
+ #
+
+ chart = lv.chart(lv.scr_act())
+ chart.set_size(200, 150)
+ chart.align(lv.ALIGN.CENTER, 0, -10)
+
+ chart.set_axis_tick(lv.chart.AXIS.PRIMARY_Y, 10, 5, 6, 5, True, 40)
+ chart.set_axis_tick(lv.chart.AXIS.PRIMARY_X, 10, 5, 10, 1, True, 30)
+
+ chart.add_event_cb(self.event_cb, lv.EVENT.ALL, None)
+ chart.refresh_ext_draw_size()
+
+ self.cursor = chart.add_cursor(lv.palette_main(lv.PALETTE.BLUE), lv.DIR.LEFT | lv.DIR.BOTTOM)
+
+ self.ser = chart.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+
+ self.ser_p = []
+ for i in range(10):
+ self.ser_p.append(lv.rand(10,90))
+ self.ser.y_points = self.ser_p
+
+ newser = chart.get_series_next(None)
+ # print("length of data points: ",len(newser.points))
+ chart.set_zoom_x(500)
+
+ label = lv.label(lv.scr_act())
+ label.set_text("Click on a point")
+ label.align_to(chart, lv.ALIGN.OUT_TOP_MID, 0, -5)
+
+
+ def event_cb(self,e):
+
+ code = e.get_code()
+ chart = e.get_target()
+
+ if code == lv.EVENT.VALUE_CHANGED:
+ # print("last_id: ",self.last_id)
+ self.last_id = chart.get_pressed_point()
+ if self.last_id != lv.CHART_POINT.NONE:
+ p = lv.point_t()
+ chart.get_point_pos_by_id(self.ser, self.last_id, p)
+ chart.set_cursor_point(self.cursor, None, self.last_id)
+
+ elif code == lv.EVENT.DRAW_PART_END:
+ # print("EVENT.DRAW_PART_END")
+ dsc = lv.obj_draw_part_dsc_t.__cast__(e.get_param())
+ # if dsc.p1 and dsc.p2:
+ # print("p1, p2", dsc.p1,dsc.p2)
+ # print("p1.y, p2.y", dsc.p1.y, dsc.p2.y)
+ # print("last_id: ",self.last_id)
+ if dsc.part == lv.PART.CURSOR and dsc.p1 and dsc.p2 and dsc.p1.y == dsc.p2.y and self.last_id >= 0:
+
+ v = self.ser_p[self.last_id]
+
+ # print("value: ",v)
+ value_txt = str(v)
+ size = lv.point_t()
+ lv.txt_get_size(size, value_txt, lv.font_default(), 0, 0, lv.COORD.MAX, lv.TEXT_FLAG.NONE)
+
+ a = lv.area_t()
+ a.y2 = dsc.p1.y - 5
+ a.y1 = a.y2 - size.y - 10
+ a.x1 = dsc.p1.x + 10
+ a.x2 = a.x1 + size.x + 10
+
+ draw_rect_dsc = lv.draw_rect_dsc_t()
+ draw_rect_dsc.init()
+ draw_rect_dsc.bg_color = lv.palette_main(lv.PALETTE.BLUE)
+ draw_rect_dsc.radius = 3
+
+ lv.draw_rect(a, dsc.clip_area, draw_rect_dsc)
+
+ draw_label_dsc = lv.draw_label_dsc_t()
+ draw_label_dsc.init()
+ draw_label_dsc.color = lv.color_white()
+ a.x1 += 5
+ a.x2 -= 5
+ a.y1 += 5
+ a.y2 -= 5
+ lv.draw_label(a, dsc.clip_area, draw_label_dsc, value_txt, None)
+
+example_chart_6 = ExampleChart_6()
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_7.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_7.c
new file mode 100644
index 00000000..506f8875
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_7.c
@@ -0,0 +1,66 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_BUILD_EXAMPLES
+
+static void draw_event_cb(lv_event_t * e)
+{
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+ if(dsc->part == LV_PART_ITEMS) {
+ lv_obj_t * obj = lv_event_get_target(e);
+ lv_chart_series_t * ser = lv_chart_get_series_next(obj, NULL);
+ uint32_t cnt = lv_chart_get_point_count(obj);
+ /*Make older value more transparent*/
+ dsc->rect_dsc->bg_opa = (LV_OPA_COVER * dsc->id) / (cnt - 1);
+
+ /*Make smaller values blue, higher values red*/
+ lv_coord_t * x_array = lv_chart_get_x_array(obj, ser);
+ lv_coord_t * y_array = lv_chart_get_y_array(obj, ser);
+ /*dsc->id is the tells drawing order, but we need the ID of the point being drawn.*/
+ uint32_t start_point = lv_chart_get_x_start_point(obj, ser);
+ uint32_t p_act = (start_point + dsc->id) % cnt; /*Consider start point to get the index of the array*/
+ lv_opa_t x_opa = (x_array[p_act] * LV_OPA_50) / 200;
+ lv_opa_t y_opa = (y_array[p_act] * LV_OPA_50) / 1000;
+
+ dsc->rect_dsc->bg_color = lv_color_mix(lv_palette_main(LV_PALETTE_RED),
+ lv_palette_main(LV_PALETTE_BLUE),
+ x_opa + y_opa);
+ }
+}
+
+static void add_data(lv_timer_t * timer)
+{
+ LV_UNUSED(timer);
+ lv_obj_t * chart = timer->user_data;
+ lv_chart_set_next_value2(chart, lv_chart_get_series_next(chart, NULL), lv_rand(0, 200), lv_rand(0, 1000));
+}
+
+/**
+ * A scatter chart
+ */
+void lv_example_chart_7(void)
+{
+ lv_obj_t * chart = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(chart, 200, 150);
+ lv_obj_align(chart, LV_ALIGN_CENTER, 0, 0);
+ lv_obj_add_event_cb(chart, draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
+ lv_obj_set_style_line_width(chart, 0, LV_PART_ITEMS); /*Remove the lines*/
+
+ lv_chart_set_type(chart, LV_CHART_TYPE_SCATTER);
+
+ lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_X, 5, 5, 5, 1, true, 30);
+ lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_Y, 10, 5, 6, 5, true, 50);
+
+ lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_X, 0, 200);
+ lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 1000);
+
+ lv_chart_set_point_count(chart, 50);
+
+ lv_chart_series_t * ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
+ uint32_t i;
+ for(i = 0; i < 50; i++) {
+ lv_chart_set_next_value2(chart, ser, lv_rand(0, 200), lv_rand(0, 1000));
+ }
+
+ lv_timer_create(add_data, 100, chart);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_7.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_7.py
new file mode 100644
index 00000000..23f17e14
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_7.py
@@ -0,0 +1,77 @@
+#!/opt/bin/lv_micropython -i
+import utime as time
+import lvgl as lv
+import display_driver
+
+def draw_event_cb(e):
+ dsc = e.get_draw_part_dsc()
+ if dsc.part == lv.PART.ITEMS:
+ obj = e.get_target()
+ ser = obj.get_series_next(None)
+ cnt = obj.get_point_count()
+ # print("cnt: ",cnt)
+ # Make older value more transparent
+ dsc.rect_dsc.bg_opa = (lv.OPA.COVER * dsc.id) // (cnt - 1)
+
+ # Make smaller values blue, higher values red
+ # x_array = chart.get_x_array(ser)
+ # y_array = chart.get_y_array(ser)
+ # dsc->id is the tells drawing order, but we need the ID of the point being drawn.
+ start_point = chart.get_x_start_point(ser)
+ # print("start point: ",start_point)
+ p_act = (start_point + dsc.id) % cnt # Consider start point to get the index of the array
+ # print("p_act", p_act)
+ x_opa = (x_array[p_act] * lv.OPA._50) // 200
+ y_opa = (y_array[p_act] * lv.OPA._50) // 1000
+
+ dsc.rect_dsc.bg_color = lv.palette_main(lv.PALETTE.RED).color_mix(
+ lv.palette_main(lv.PALETTE.BLUE),
+ x_opa + y_opa)
+
+def add_data(timer,chart):
+ # print("add_data")
+ x = lv.rand(0,200)
+ y = lv.rand(0,1000)
+ chart.set_next_value2(ser, x, y)
+ # chart.set_next_value2(chart.gx, y)
+ x_array.pop(0)
+ x_array.append(x)
+ y_array.pop(0)
+ y_array.append(y)
+
+#
+# A scatter chart
+#
+
+chart = lv.chart(lv.scr_act())
+chart.set_size(200, 150)
+chart.align(lv.ALIGN.CENTER, 0, 0)
+chart.add_event_cb(draw_event_cb, lv.EVENT.DRAW_PART_BEGIN, None)
+chart.set_style_line_width(0, lv.PART.ITEMS) # Remove the lines
+
+chart.set_type(lv.chart.TYPE.SCATTER)
+
+chart.set_axis_tick(lv.chart.AXIS.PRIMARY_X, 5, 5, 5, 1, True, 30)
+chart.set_axis_tick(lv.chart.AXIS.PRIMARY_Y, 10, 5, 6, 5, True, 50)
+
+chart.set_range(lv.chart.AXIS.PRIMARY_X, 0, 200)
+chart.set_range(lv.chart.AXIS.PRIMARY_Y, 0, 1000)
+
+chart.set_point_count(50)
+
+ser = chart.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+
+x_array = []
+y_array = []
+for i in range(50):
+ x_array.append(lv.rand(0, 200))
+ y_array.append(lv.rand(0, 1000))
+
+ser.x_points = x_array
+ser.y_points = y_array
+
+# Create an `lv_timer` to update the chart.
+
+timer = lv.timer_create_basic()
+timer.set_period(100)
+timer.set_cb(lambda src: add_data(timer,chart))
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_8.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_8.c
new file mode 100644
index 00000000..ca2c8f8c
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_8.c
@@ -0,0 +1,131 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_DRAW_COMPLEX && LV_BUILD_EXAMPLES
+
+/* A struct is used to keep track of the series list because later we need to draw to the series in the reverse order to which they were initialised. */
+typedef struct {
+ lv_obj_t * obj;
+ lv_chart_series_t * series_list[3];
+} stacked_area_chart_t;
+
+static stacked_area_chart_t stacked_area_chart;
+
+/**
+ * Callback which draws the blocks of colour under the lines
+ **/
+static void draw_event_cb(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+
+ /*Add the faded area before the lines are drawn*/
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+ if(dsc->part == LV_PART_ITEMS) {
+ if(!dsc->p1 || !dsc->p2)
+ return;
+
+ /*Add a line mask that keeps the area below the line*/
+ lv_draw_mask_line_param_t line_mask_param;
+ lv_draw_mask_line_points_init(&line_mask_param, dsc->p1->x, dsc->p1->y, dsc->p2->x, dsc->p2->y,
+ LV_DRAW_MASK_LINE_SIDE_BOTTOM);
+ int16_t line_mask_id = lv_draw_mask_add(&line_mask_param, NULL);
+
+ /*Draw a rectangle that will be affected by the mask*/
+ lv_draw_rect_dsc_t draw_rect_dsc;
+ lv_draw_rect_dsc_init(&draw_rect_dsc);
+ draw_rect_dsc.bg_opa = LV_OPA_COVER;
+ draw_rect_dsc.bg_color = dsc->line_dsc->color;
+
+ lv_area_t a;
+ a.x1 = dsc->p1->x;
+ a.x2 = dsc->p2->x;
+ a.y1 = LV_MIN(dsc->p1->y, dsc->p2->y);
+ a.y2 = obj->coords.y2 -
+ 13; /* -13 cuts off where the rectangle draws over the chart margin. Without this an area of 0 doesn't look like 0 */
+ lv_draw_rect(dsc->draw_ctx, &draw_rect_dsc, &a);
+
+ /*Remove the mask*/
+ lv_draw_mask_free_param(&line_mask_param);
+ lv_draw_mask_remove_id(line_mask_id);
+ }
+}
+
+/**
+ * Helper function to round a fixed point number
+ **/
+static int32_t round_fixed_point(int32_t n, int8_t shift)
+{
+ /* Create a bitmask to isolates the decimal part of the fixed point number */
+ int32_t mask = 1;
+ for(int32_t bit_pos = 0; bit_pos < shift; bit_pos++) {
+ mask = (mask << 1) + 1;
+ }
+
+ int32_t decimal_part = n & mask;
+
+ /* Get 0.5 as fixed point */
+ int32_t rounding_boundary = 1 << (shift - 1);
+
+ /* Return either the integer part of n or the integer part + 1 */
+ return (decimal_part < rounding_boundary) ? (n & ~mask) : ((n >> shift) + 1) << shift;
+}
+
+/**
+ * Stacked area chart
+ */
+void lv_example_chart_8(void)
+{
+ /*Create a stacked_area_chart.obj*/
+ stacked_area_chart.obj = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(stacked_area_chart.obj, 200, 150);
+ lv_obj_center(stacked_area_chart.obj);
+ lv_chart_set_type(stacked_area_chart.obj, LV_CHART_TYPE_LINE);
+ lv_chart_set_div_line_count(stacked_area_chart.obj, 5, 7);
+ lv_obj_add_event_cb(stacked_area_chart.obj, draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
+
+ /* Set range to 0 to 100 for percentages. Draw ticks */
+ lv_chart_set_range(stacked_area_chart.obj, LV_CHART_AXIS_PRIMARY_Y, 0, 100);
+ lv_chart_set_axis_tick(stacked_area_chart.obj, LV_CHART_AXIS_PRIMARY_Y, 3, 0, 5, 1, true, 30);
+
+ /*Set point size to 0 so the lines are smooth */
+ lv_obj_set_style_size(stacked_area_chart.obj, 0, LV_PART_INDICATOR);
+
+ /*Add some data series*/
+ stacked_area_chart.series_list[0] = lv_chart_add_series(stacked_area_chart.obj, lv_palette_main(LV_PALETTE_RED),
+ LV_CHART_AXIS_PRIMARY_Y);
+ stacked_area_chart.series_list[1] = lv_chart_add_series(stacked_area_chart.obj, lv_palette_main(LV_PALETTE_BLUE),
+ LV_CHART_AXIS_PRIMARY_Y);
+ stacked_area_chart.series_list[2] = lv_chart_add_series(stacked_area_chart.obj, lv_palette_main(LV_PALETTE_GREEN),
+ LV_CHART_AXIS_PRIMARY_Y);
+
+ for(int point = 0; point < 10; point++) {
+ /* Make some random data */
+ uint32_t vals[3] = {lv_rand(10, 20), lv_rand(20, 30), lv_rand(20, 30)};
+
+ int8_t fixed_point_shift = 5;
+ uint32_t total = vals[0] + vals[1] + vals[2];
+ uint32_t draw_heights[3];
+ uint32_t int_sum = 0;
+ uint32_t decimal_sum = 0;
+
+ /* Fixed point cascade rounding ensures percentages add to 100 */
+ for(int32_t series_index = 0; series_index < 3; series_index++) {
+ decimal_sum += (((vals[series_index] * 100) << fixed_point_shift) / total);
+ int_sum += (vals[series_index] * 100) / total;
+
+ int32_t modifier = (round_fixed_point(decimal_sum, fixed_point_shift) >> fixed_point_shift) - int_sum;
+
+ /* The draw heights are equal to the percentage of the total each value is + the cumulative sum of the previous percentages.
+ The accumulation is how the values get "stacked" */
+ draw_heights[series_index] = int_sum + modifier;
+
+ /* Draw to the series in the reverse order to which they were initialised.
+ Without this the higher values will draw on top of the lower ones.
+ This is because the Z-height of a series matches the order it was initialised */
+ lv_chart_set_next_value(stacked_area_chart.obj, stacked_area_chart.series_list[3 - series_index - 1],
+ draw_heights[series_index]);
+ }
+ }
+
+ lv_chart_refresh(stacked_area_chart.obj);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_8.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_8.py
new file mode 100644
index 00000000..20996b3a
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_8.py
@@ -0,0 +1,124 @@
+import display_driver
+import lvgl as lv
+
+# A class is used to keep track of the series list because later we
+# need to draw to the series in the reverse order to which they were initialised.
+class StackedAreaChart:
+ def __init__(self):
+ self.obj = None
+ self.series_list = [None, None, None]
+
+stacked_area_chart = StackedAreaChart()
+
+#
+# Callback which draws the blocks of colour under the lines
+#
+def draw_event_cb(e):
+
+ obj = e.get_target()
+ cont_a = lv.area_t()
+ obj.get_coords(cont_a)
+
+ #Add the faded area before the lines are drawn
+ dsc = e.get_draw_part_dsc()
+ if dsc.part == lv.PART.ITEMS:
+ if not dsc.p1 or not dsc.p2:
+ return
+
+ # Add a line mask that keeps the area below the line
+ line_mask_param = lv.draw_mask_line_param_t()
+ line_mask_param.points_init(dsc.p1.x, dsc.p1.y, dsc.p2.x, dsc.p2.y, lv.DRAW_MASK_LINE_SIDE.BOTTOM)
+ line_mask_id = lv.draw_mask_add(line_mask_param, None)
+
+ #Draw a rectangle that will be affected by the mask
+ draw_rect_dsc = lv.draw_rect_dsc_t()
+ draw_rect_dsc.init()
+ draw_rect_dsc.bg_opa = lv.OPA.COVER
+ draw_rect_dsc.bg_color = dsc.line_dsc.color
+
+ a = lv.area_t()
+ a.x1 = dsc.p1.x
+ a.x2 = dsc.p2.x
+ a.y1 = min(dsc.p1.y, dsc.p2.y)
+ a.y2 = cont_a.y2 - 13 # -13 cuts off where the rectangle draws over the chart margin. Without this an area of 0 doesn't look like 0
+ dsc.draw_ctx.rect(draw_rect_dsc, a)
+
+ # Remove the mask
+ lv.draw_mask_free_param(line_mask_param)
+ lv.draw_mask_remove_id(line_mask_id)
+
+
+#
+# Helper function to round a fixed point number
+#
+def round_fixed_point(n, shift):
+ # Create a bitmask to isolates the decimal part of the fixed point number
+ mask = 1
+ for bit_pos in range(shift):
+ mask = (mask << 1) + 1
+
+ decimal_part = n & mask
+
+ # Get 0.5 as fixed point
+ rounding_boundary = 1 << (shift - 1)
+
+ # Return either the integer part of n or the integer part + 1
+ if decimal_part < rounding_boundary:
+ return (n & ~mask)
+ return ((n >> shift) + 1) << shift
+
+
+#
+# Stacked area chart
+#
+def lv_example_chart_8():
+
+ #Create a stacked_area_chart.obj
+ stacked_area_chart.obj = lv.chart(lv.scr_act())
+ stacked_area_chart.obj.set_size(200, 150)
+ stacked_area_chart.obj.center()
+ stacked_area_chart.obj.set_type( lv.chart.TYPE.LINE)
+ stacked_area_chart.obj.set_div_line_count(5, 7)
+ stacked_area_chart.obj.add_event_cb( draw_event_cb, lv.EVENT.DRAW_PART_BEGIN, None)
+
+ # Set range to 0 to 100 for percentages. Draw ticks
+ stacked_area_chart.obj.set_range(lv.chart.AXIS.PRIMARY_Y,0,100)
+ stacked_area_chart.obj.set_axis_tick(lv.chart.AXIS.PRIMARY_Y, 3, 0, 5, 1, True, 30)
+
+ #Set point size to 0 so the lines are smooth
+ stacked_area_chart.obj.set_style_size(0, lv.PART.INDICATOR)
+
+ # Add some data series
+ stacked_area_chart.series_list[0] = stacked_area_chart.obj.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+ stacked_area_chart.series_list[1] = stacked_area_chart.obj.add_series(lv.palette_main(lv.PALETTE.BLUE), lv.chart.AXIS.PRIMARY_Y)
+ stacked_area_chart.series_list[2] = stacked_area_chart.obj.add_series(lv.palette_main(lv.PALETTE.GREEN), lv.chart.AXIS.PRIMARY_Y)
+
+ for point in range(10):
+ # Make some random data
+ vals = [lv.rand(10, 20), lv.rand(20, 30), lv.rand(20, 30)]
+
+ fixed_point_shift = 5
+ total = vals[0] + vals[1] + vals[2]
+ draw_heights = [0, 0, 0]
+ int_sum = 0
+ decimal_sum = 0
+
+ # Fixed point cascade rounding ensures percentages add to 100
+ for series_index in range(3):
+ decimal_sum += int(((vals[series_index] * 100) << fixed_point_shift) // total)
+ int_sum += int((vals[series_index] * 100) / total)
+
+ modifier = (round_fixed_point(decimal_sum, fixed_point_shift) >> fixed_point_shift) - int_sum
+
+ # The draw heights are equal to the percentage of the total each value is + the cumulative sum of the previous percentages.
+ # The accumulation is how the values get "stacked"
+ draw_heights[series_index] = int(int_sum + modifier)
+
+ # Draw to the series in the reverse order to which they were initialised.
+ # Without this the higher values will draw on top of the lower ones.
+ # This is because the Z-height of a series matches the order it was initialised
+ stacked_area_chart.obj.set_next_value( stacked_area_chart.series_list[3 - series_index - 1], draw_heights[series_index])
+
+ stacked_area_chart.obj.refresh()
+
+lv_example_chart_8()
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_9.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_9.c
new file mode 100644
index 00000000..c94b564f
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_9.c
@@ -0,0 +1,46 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_DRAW_COMPLEX && LV_BUILD_EXAMPLES
+
+
+static void add_data(lv_timer_t * t)
+{
+ lv_obj_t * chart = t->user_data;
+ lv_chart_series_t * ser = lv_chart_get_series_next(chart, NULL);
+
+ lv_chart_set_next_value(chart, ser, lv_rand(10, 90));
+
+ uint16_t p = lv_chart_get_point_count(chart);
+ uint16_t s = lv_chart_get_x_start_point(chart, ser);
+ lv_coord_t * a = lv_chart_get_y_array(chart, ser);
+
+ a[(s + 1) % p] = LV_CHART_POINT_NONE;
+ a[(s + 2) % p] = LV_CHART_POINT_NONE;
+ a[(s + 2) % p] = LV_CHART_POINT_NONE;
+
+ lv_chart_refresh(chart);
+}
+
+/**
+ * Circular line chart with gap
+ */
+void lv_example_chart_9(void)
+{
+ /*Create a stacked_area_chart.obj*/
+ lv_obj_t * chart = lv_chart_create(lv_scr_act());
+ lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_CIRCULAR);
+ lv_obj_set_size(chart, 200, 150);
+ lv_obj_center(chart);
+
+ lv_chart_set_point_count(chart, 30);
+ lv_chart_series_t * ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
+ /*Prefill with data*/
+ uint32_t i;
+ for(i = 0; i < 30; i++) {
+ lv_chart_set_next_value(chart, ser, lv_rand(10, 90));
+ }
+
+ lv_timer_create(add_data, 300, chart);
+
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_9.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_9.py
new file mode 100644
index 00000000..37b16b39
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_9.py
@@ -0,0 +1,31 @@
+import display_driver
+import lvgl as lv
+
+def add_data(t):
+ chart.set_next_value(ser, lv.rand(10, 90))
+
+ p = chart.get_point_count()
+ s = chart.get_x_start_point(ser)
+ a = chart.get_y_array(ser)
+
+ a[(s + 1) % p] = lv.CHART_POINT.NONE
+ a[(s + 2) % p] = lv.CHART_POINT.NONE
+ a[(s + 3) % p] = lv.CHART_POINT.NONE
+ chart.refresh()
+
+#
+# Circular line chart with gap
+#
+chart = lv.chart(lv.scr_act())
+
+chart.set_update_mode(lv.chart.UPDATE_MODE.CIRCULAR)
+chart.set_size(200, 150)
+chart.center()
+
+chart.set_point_count(30)
+ser = chart.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+#Prefill with data
+for i in range(0, 30):
+ chart.set_next_value(ser, lv.rand(10, 90))
+
+lv.timer_create(add_data, 200, None)
diff --git a/lib/lvgl/examples/widgets/checkbox/index.rst b/lib/lvgl/examples/widgets/checkbox/index.rst
new file mode 100644
index 00000000..e24f0142
--- /dev/null
+++ b/lib/lvgl/examples/widgets/checkbox/index.rst
@@ -0,0 +1,12 @@
+
+Simple Checkboxes
+"""""""""""""""""
+
+.. lv_example:: widgets/checkbox/lv_example_checkbox_1
+ :language: c
+
+Checkboxes as radio buttons
+"""""""""""""""""""""""""""
+.. lv_example:: widgets/checkbox/lv_example_checkbox_2
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/checkbox/lv_example_checkbox_1.c b/lib/lvgl/examples/widgets/checkbox/lv_example_checkbox_1.c
new file mode 100644
index 00000000..ff59bd99
--- /dev/null
+++ b/lib/lvgl/examples/widgets/checkbox/lv_example_checkbox_1.c
@@ -0,0 +1,43 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHECKBOX && LV_BUILD_EXAMPLES
+
+static void event_handler(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+ if(code == LV_EVENT_VALUE_CHANGED) {
+ const char * txt = lv_checkbox_get_text(obj);
+ const char * state = lv_obj_get_state(obj) & LV_STATE_CHECKED ? "Checked" : "Unchecked";
+ LV_LOG_USER("%s: %s", txt, state);
+ }
+}
+
+void lv_example_checkbox_1(void)
+{
+ lv_obj_set_flex_flow(lv_scr_act(), LV_FLEX_FLOW_COLUMN);
+ lv_obj_set_flex_align(lv_scr_act(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER);
+
+ lv_obj_t * cb;
+ cb = lv_checkbox_create(lv_scr_act());
+ lv_checkbox_set_text(cb, "Apple");
+ lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL);
+
+ cb = lv_checkbox_create(lv_scr_act());
+ lv_checkbox_set_text(cb, "Banana");
+ lv_obj_add_state(cb, LV_STATE_CHECKED);
+ lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL);
+
+ cb = lv_checkbox_create(lv_scr_act());
+ lv_checkbox_set_text(cb, "Lemon");
+ lv_obj_add_state(cb, LV_STATE_DISABLED);
+ lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL);
+
+ cb = lv_checkbox_create(lv_scr_act());
+ lv_obj_add_state(cb, LV_STATE_CHECKED | LV_STATE_DISABLED);
+ lv_checkbox_set_text(cb, "Melon\nand a new line");
+ lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL);
+
+ lv_obj_update_layout(cb);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/checkbox/lv_example_checkbox_1.py b/lib/lvgl/examples/widgets/checkbox/lv_example_checkbox_1.py
new file mode 100644
index 00000000..e2c9a1b0
--- /dev/null
+++ b/lib/lvgl/examples/widgets/checkbox/lv_example_checkbox_1.py
@@ -0,0 +1,36 @@
+def event_handler(e):
+ code = e.get_code()
+ obj = e.get_target()
+ if code == lv.EVENT.VALUE_CHANGED:
+ txt = obj.get_text()
+ if obj.get_state() & lv.STATE.CHECKED:
+ state = "Checked"
+ else:
+ state = "Unchecked"
+ print(txt + ":" + state)
+
+
+lv.scr_act().set_flex_flow(lv.FLEX_FLOW.COLUMN)
+lv.scr_act().set_flex_align(lv.FLEX_ALIGN.CENTER, lv.FLEX_ALIGN.START, lv.FLEX_ALIGN.CENTER)
+
+cb = lv.checkbox(lv.scr_act())
+cb.set_text("Apple")
+cb.add_event_cb(event_handler, lv.EVENT.ALL, None)
+
+cb = lv.checkbox(lv.scr_act())
+cb.set_text("Banana")
+cb.add_state(lv.STATE.CHECKED)
+cb.add_event_cb(event_handler, lv.EVENT.ALL, None)
+
+cb = lv.checkbox(lv.scr_act())
+cb.set_text("Lemon")
+cb.add_state(lv.STATE.DISABLED)
+cb.add_event_cb(event_handler, lv.EVENT.ALL, None)
+
+cb = lv.checkbox(lv.scr_act())
+cb.add_state(lv.STATE.CHECKED | lv.STATE.DISABLED)
+cb.set_text("Melon")
+cb.add_event_cb(event_handler, lv.EVENT.ALL, None)
+
+cb.update_layout()
+
diff --git a/lib/lvgl/examples/widgets/checkbox/lv_example_checkbox_2.c b/lib/lvgl/examples/widgets/checkbox/lv_example_checkbox_2.c
new file mode 100644
index 00000000..02a57289
--- /dev/null
+++ b/lib/lvgl/examples/widgets/checkbox/lv_example_checkbox_2.c
@@ -0,0 +1,86 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHECKBOX && LV_BUILD_EXAMPLES
+
+static lv_style_t style_radio;
+static lv_style_t style_radio_chk;
+static uint32_t active_index_1 = 0;
+static uint32_t active_index_2 = 0;
+
+static void radio_event_handler(lv_event_t * e)
+{
+ uint32_t * active_id = lv_event_get_user_data(e);
+ lv_obj_t * cont = lv_event_get_current_target(e);
+ lv_obj_t * act_cb = lv_event_get_target(e);
+ lv_obj_t * old_cb = lv_obj_get_child(cont, *active_id);
+
+ /*Do nothing if the container was clicked*/
+ if(act_cb == cont) return;
+
+ lv_obj_clear_state(old_cb, LV_STATE_CHECKED); /*Uncheck the previous radio button*/
+ lv_obj_add_state(act_cb, LV_STATE_CHECKED); /*Uncheck the current radio button*/
+
+ *active_id = lv_obj_get_index(act_cb);
+
+ LV_LOG_USER("Selected radio buttons: %d, %d", (int)active_index_1, (int)active_index_2);
+}
+
+
+static void radiobutton_create(lv_obj_t * parent, const char * txt)
+{
+ lv_obj_t * obj = lv_checkbox_create(parent);
+ lv_checkbox_set_text(obj, txt);
+ lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE);
+ lv_obj_add_style(obj, &style_radio, LV_PART_INDICATOR);
+ lv_obj_add_style(obj, &style_radio_chk, LV_PART_INDICATOR | LV_STATE_CHECKED);
+}
+
+/**
+ * Checkboxes as radio buttons
+ */
+void lv_example_checkbox_2(void)
+{
+ /* The idea is to enable `LV_OBJ_FLAG_EVENT_BUBBLE` on checkboxes and process the
+ * `LV_EVENT_CLICKED` on the container.
+ * A variable is passed as event user data where the index of the active
+ * radiobutton is saved */
+
+
+ lv_style_init(&style_radio);
+ lv_style_set_radius(&style_radio, LV_RADIUS_CIRCLE);
+
+ lv_style_init(&style_radio_chk);
+ lv_style_set_bg_img_src(&style_radio_chk, NULL);
+
+ uint32_t i;
+ char buf[32];
+
+ lv_obj_t * cont1 = lv_obj_create(lv_scr_act());
+ lv_obj_set_flex_flow(cont1, LV_FLEX_FLOW_COLUMN);
+ lv_obj_set_size(cont1, lv_pct(40), lv_pct(80));
+ lv_obj_add_event_cb(cont1, radio_event_handler, LV_EVENT_CLICKED, &active_index_1);
+
+ for(i = 0; i < 5; i++) {
+ lv_snprintf(buf, sizeof(buf), "A %d", (int)i + 1);
+ radiobutton_create(cont1, buf);
+
+ }
+ /*Make the first checkbox checked*/
+ lv_obj_add_state(lv_obj_get_child(cont1, 0), LV_STATE_CHECKED);
+
+ lv_obj_t * cont2 = lv_obj_create(lv_scr_act());
+ lv_obj_set_flex_flow(cont2, LV_FLEX_FLOW_COLUMN);
+ lv_obj_set_size(cont2, lv_pct(40), lv_pct(80));
+ lv_obj_set_x(cont2, lv_pct(50));
+ lv_obj_add_event_cb(cont2, radio_event_handler, LV_EVENT_CLICKED, &active_index_2);
+
+ for(i = 0; i < 3; i++) {
+ lv_snprintf(buf, sizeof(buf), "B %d", (int)i + 1);
+ radiobutton_create(cont2, buf);
+ }
+
+ /*Make the first checkbox checked*/
+ lv_obj_add_state(lv_obj_get_child(cont2, 0), LV_STATE_CHECKED);
+}
+
+
+#endif
diff --git a/lib/lvgl/examples/widgets/colorwheel/index.rst b/lib/lvgl/examples/widgets/colorwheel/index.rst
new file mode 100644
index 00000000..342be739
--- /dev/null
+++ b/lib/lvgl/examples/widgets/colorwheel/index.rst
@@ -0,0 +1,7 @@
+
+Simple Colorwheel
+"""""""""""""""""
+
+.. lv_example:: widgets/colorwheel/lv_example_colorwheel_1
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/colorwheel/lv_example_colorwheel_1.c b/lib/lvgl/examples/widgets/colorwheel/lv_example_colorwheel_1.c
new file mode 100644
index 00000000..7e4f42d0
--- /dev/null
+++ b/lib/lvgl/examples/widgets/colorwheel/lv_example_colorwheel_1.c
@@ -0,0 +1,13 @@
+#include "../../lv_examples.h"
+#if LV_USE_COLORWHEEL && LV_BUILD_EXAMPLES
+
+void lv_example_colorwheel_1(void)
+{
+ lv_obj_t * cw;
+
+ cw = lv_colorwheel_create(lv_scr_act(), true);
+ lv_obj_set_size(cw, 200, 200);
+ lv_obj_center(cw);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/colorwheel/lv_example_colorwheel_1.py b/lib/lvgl/examples/widgets/colorwheel/lv_example_colorwheel_1.py
new file mode 100644
index 00000000..3da373d6
--- /dev/null
+++ b/lib/lvgl/examples/widgets/colorwheel/lv_example_colorwheel_1.py
@@ -0,0 +1,4 @@
+cw = lv.colorwheel(lv.scr_act(), True)
+cw.set_size(200, 200)
+cw.center()
+
diff --git a/lib/lvgl/examples/widgets/dropdown/index.rst b/lib/lvgl/examples/widgets/dropdown/index.rst
new file mode 100644
index 00000000..c396361a
--- /dev/null
+++ b/lib/lvgl/examples/widgets/dropdown/index.rst
@@ -0,0 +1,20 @@
+
+Simple Drop down list
+""""""""""""""""""""""
+
+.. lv_example:: widgets/dropdown/lv_example_dropdown_1
+ :language: c
+
+Drop down in four directions
+""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/dropdown/lv_example_dropdown_2
+ :language: c
+
+
+Menu
+""""""""""""
+
+.. lv_example:: widgets/dropdown/lv_example_dropdown_3
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_1.c b/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_1.c
new file mode 100644
index 00000000..275e6cf6
--- /dev/null
+++ b/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_1.c
@@ -0,0 +1,35 @@
+#include "../../lv_examples.h"
+#if LV_USE_DROPDOWN && LV_BUILD_EXAMPLES
+
+static void event_handler(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+ if(code == LV_EVENT_VALUE_CHANGED) {
+ char buf[32];
+ lv_dropdown_get_selected_str(obj, buf, sizeof(buf));
+ LV_LOG_USER("Option: %s", buf);
+ }
+}
+
+void lv_example_dropdown_1(void)
+{
+
+ /*Create a normal drop down list*/
+ lv_obj_t * dd = lv_dropdown_create(lv_scr_act());
+ lv_dropdown_set_options(dd, "Apple\n"
+ "Banana\n"
+ "Orange\n"
+ "Cherry\n"
+ "Grape\n"
+ "Raspberry\n"
+ "Melon\n"
+ "Orange\n"
+ "Lemon\n"
+ "Nuts");
+
+ lv_obj_align(dd, LV_ALIGN_TOP_MID, 0, 20);
+ lv_obj_add_event_cb(dd, event_handler, LV_EVENT_ALL, NULL);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_1.py b/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_1.py
new file mode 100644
index 00000000..ad7621e1
--- /dev/null
+++ b/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_1.py
@@ -0,0 +1,26 @@
+def event_handler(e):
+ code = e.get_code()
+ obj = e.get_target()
+ if code == lv.EVENT.VALUE_CHANGED:
+ option = " "*10 # should be large enough to store the option
+ obj.get_selected_str(option, len(option))
+ # .strip() removes trailing spaces
+ print("Option: \"%s\"" % option.strip())
+
+# Create a normal drop down list
+dd = lv.dropdown(lv.scr_act())
+dd.set_options("\n".join([
+ "Apple",
+ "Banana",
+ "Orange",
+ "Cherry",
+ "Grape",
+ "Raspberry",
+ "Melon",
+ "Orange",
+ "Lemon",
+ "Nuts"]))
+
+dd.align(lv.ALIGN.TOP_MID, 0, 20)
+dd.add_event_cb(event_handler, lv.EVENT.ALL, None)
+
diff --git a/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_2.c b/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_2.c
new file mode 100644
index 00000000..77f15791
--- /dev/null
+++ b/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_2.c
@@ -0,0 +1,39 @@
+#include "../../lv_examples.h"
+#if LV_USE_DROPDOWN && LV_BUILD_EXAMPLES
+
+
+/**
+ * Create a drop down, up, left and right menus
+ */
+void lv_example_dropdown_2(void)
+{
+ static const char * opts = "Apple\n"
+ "Banana\n"
+ "Orange\n"
+ "Melon";
+
+ lv_obj_t * dd;
+ dd = lv_dropdown_create(lv_scr_act());
+ lv_dropdown_set_options_static(dd, opts);
+ lv_obj_align(dd, LV_ALIGN_TOP_MID, 0, 10);
+
+ dd = lv_dropdown_create(lv_scr_act());
+ lv_dropdown_set_options_static(dd, opts);
+ lv_dropdown_set_dir(dd, LV_DIR_BOTTOM);
+ lv_dropdown_set_symbol(dd, LV_SYMBOL_UP);
+ lv_obj_align(dd, LV_ALIGN_BOTTOM_MID, 0, -10);
+
+ dd = lv_dropdown_create(lv_scr_act());
+ lv_dropdown_set_options_static(dd, opts);
+ lv_dropdown_set_dir(dd, LV_DIR_RIGHT);
+ lv_dropdown_set_symbol(dd, LV_SYMBOL_RIGHT);
+ lv_obj_align(dd, LV_ALIGN_LEFT_MID, 10, 0);
+
+ dd = lv_dropdown_create(lv_scr_act());
+ lv_dropdown_set_options_static(dd, opts);
+ lv_dropdown_set_dir(dd, LV_DIR_LEFT);
+ lv_dropdown_set_symbol(dd, LV_SYMBOL_LEFT);
+ lv_obj_align(dd, LV_ALIGN_RIGHT_MID, -10, 0);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_2.py b/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_2.py
new file mode 100644
index 00000000..49271137
--- /dev/null
+++ b/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_2.py
@@ -0,0 +1,34 @@
+#
+# Create a drop down, up, left and right menus
+#
+
+opts = "\n".join([
+ "Apple",
+ "Banana",
+ "Orange",
+ "Melon",
+ "Grape",
+ "Raspberry"])
+
+dd = lv.dropdown(lv.scr_act())
+dd.set_options_static(opts)
+dd.align(lv.ALIGN.TOP_MID, 0, 10)
+dd = lv.dropdown(lv.scr_act())
+dd.set_options_static(opts)
+dd.set_dir(lv.DIR.BOTTOM)
+dd.set_symbol(lv.SYMBOL.UP)
+dd.align(lv.ALIGN.BOTTOM_MID, 0, -10)
+
+dd = lv.dropdown(lv.scr_act())
+dd.set_options_static(opts)
+dd.set_dir(lv.DIR.RIGHT)
+dd.set_symbol(lv.SYMBOL.RIGHT)
+dd.align(lv.ALIGN.LEFT_MID, 10, 0)
+
+dd = lv.dropdown(lv.scr_act())
+dd.set_options_static(opts)
+dd.set_dir(lv.DIR.LEFT)
+dd.set_symbol(lv.SYMBOL.LEFT)
+dd.align(lv.ALIGN.RIGHT_MID, -10, 0)
+
+
diff --git a/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_3.c b/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_3.c
new file mode 100644
index 00000000..123cb8dd
--- /dev/null
+++ b/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_3.c
@@ -0,0 +1,43 @@
+#include "../../lv_examples.h"
+#if LV_USE_DROPDOWN && LV_BUILD_EXAMPLES
+
+static void event_cb(lv_event_t * e)
+{
+ lv_obj_t * dropdown = lv_event_get_target(e);
+ char buf[64];
+ lv_dropdown_get_selected_str(dropdown, buf, sizeof(buf));
+ LV_LOG_USER("'%s' is selected", buf);
+}
+
+/**
+ * Create a menu from a drop-down list and show some drop-down list features and styling
+ */
+void lv_example_dropdown_3(void)
+{
+ /*Create a drop down list*/
+ lv_obj_t * dropdown = lv_dropdown_create(lv_scr_act());
+ lv_obj_align(dropdown, LV_ALIGN_TOP_LEFT, 10, 10);
+ lv_dropdown_set_options(dropdown, "New project\n"
+ "New file\n"
+ "Save\n"
+ "Save as ...\n"
+ "Open project\n"
+ "Recent projects\n"
+ "Preferences\n"
+ "Exit");
+
+ /*Set a fixed text to display on the button of the drop-down list*/
+ lv_dropdown_set_text(dropdown, "Menu");
+
+ /*Use a custom image as down icon and flip it when the list is opened*/
+ LV_IMG_DECLARE(img_caret_down)
+ lv_dropdown_set_symbol(dropdown, &img_caret_down);
+ lv_obj_set_style_transform_angle(dropdown, 1800, LV_PART_INDICATOR | LV_STATE_CHECKED);
+
+ /*In a menu we don't need to show the last clicked item*/
+ lv_dropdown_set_selected_highlight(dropdown, false);
+
+ lv_obj_add_event_cb(dropdown, event_cb, LV_EVENT_VALUE_CHANGED, NULL);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_3.py b/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_3.py
new file mode 100644
index 00000000..07ba0718
--- /dev/null
+++ b/lib/lvgl/examples/widgets/dropdown/lv_example_dropdown_3.py
@@ -0,0 +1,53 @@
+from imagetools import get_png_info, open_png
+
+# Register PNG image decoder
+decoder = lv.img.decoder_create()
+decoder.info_cb = get_png_info
+decoder.open_cb = open_png
+
+# Create an image from the png file
+try:
+ with open('../../assets/img_caret_down.png','rb') as f:
+ png_data = f.read()
+except:
+ print("Could not find img_caret_down.png")
+ sys.exit()
+
+img_caret_down_argb = lv.img_dsc_t({
+ 'data_size': len(png_data),
+ 'data': png_data
+})
+
+def event_cb(e):
+ dropdown = e.get_target()
+ option = " "*64 # should be large enough to store the option
+ dropdown.get_selected_str(option, len(option))
+ print(option.strip() +" is selected")
+#
+# Create a menu from a drop-down list and show some drop-down list features and styling
+#
+
+# Create a drop down list
+dropdown = lv.dropdown(lv.scr_act())
+dropdown.align(lv.ALIGN.TOP_LEFT, 10, 10)
+dropdown.set_options("\n".join([
+ "New project",
+ "New file",
+ "Open project",
+ "Recent projects",
+ "Preferences",
+ "Exit"]))
+
+# Set a fixed text to display on the button of the drop-down list
+dropdown.set_text("Menu")
+
+# Use a custom image as down icon and flip it when the list is opened
+# LV_IMG_DECLARE(img_caret_down)
+dropdown.set_symbol(img_caret_down_argb)
+dropdown.set_style_transform_angle(1800, lv.PART.INDICATOR | lv.STATE.CHECKED)
+
+# In a menu we don't need to show the last clicked item
+dropdown.set_selected_highlight(False)
+
+dropdown.add_event_cb(event_cb, lv.EVENT.VALUE_CHANGED, None)
+
diff --git a/lib/lvgl/examples/widgets/img/index.rst b/lib/lvgl/examples/widgets/img/index.rst
new file mode 100644
index 00000000..efba6b42
--- /dev/null
+++ b/lib/lvgl/examples/widgets/img/index.rst
@@ -0,0 +1,28 @@
+
+Image from variable and symbol
+"""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/img/lv_example_img_1
+ :language: c
+
+
+Image recoloring
+""""""""""""""""
+
+.. lv_example:: widgets/img/lv_example_img_2
+ :language: c
+
+
+Rotate and zoom
+""""""""""""""""
+
+.. lv_example:: widgets/img/lv_example_img_3
+ :language: c
+
+Image offset and styling
+""""""""""""""""""""""""
+
+.. lv_example:: widgets/img/lv_example_img_4
+ :language: c
+
+
diff --git a/lib/lvgl/examples/widgets/img/lv_example_img_1.c b/lib/lvgl/examples/widgets/img/lv_example_img_1.c
new file mode 100644
index 00000000..76ef1f41
--- /dev/null
+++ b/lib/lvgl/examples/widgets/img/lv_example_img_1.c
@@ -0,0 +1,18 @@
+#include "../../lv_examples.h"
+#if LV_USE_IMG && LV_BUILD_EXAMPLES
+
+
+void lv_example_img_1(void)
+{
+ LV_IMG_DECLARE(img_cogwheel_argb);
+ lv_obj_t * img1 = lv_img_create(lv_scr_act());
+ lv_img_set_src(img1, &img_cogwheel_argb);
+ lv_obj_align(img1, LV_ALIGN_CENTER, 0, -20);
+ lv_obj_set_size(img1, 200, 200);
+
+ lv_obj_t * img2 = lv_img_create(lv_scr_act());
+ lv_img_set_src(img2, LV_SYMBOL_OK "Accept");
+ lv_obj_align_to(img2, img1, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/img/lv_example_img_1.py b/lib/lvgl/examples/widgets/img/lv_example_img_1.py
new file mode 100644
index 00000000..b5242f65
--- /dev/null
+++ b/lib/lvgl/examples/widgets/img/lv_example_img_1.py
@@ -0,0 +1,32 @@
+#!/opt/bin/lv_micropython -i
+import usys as sys
+import lvgl as lv
+import display_driver
+from imagetools import get_png_info, open_png
+
+# Register PNG image decoder
+decoder = lv.img.decoder_create()
+decoder.info_cb = get_png_info
+decoder.open_cb = open_png
+
+# Create an image from the png file
+try:
+ with open('../../assets/img_cogwheel_argb.png','rb') as f:
+ png_data = f.read()
+except:
+ print("Could not find img_cogwheel_argb.png")
+ sys.exit()
+
+img_cogwheel_argb = lv.img_dsc_t({
+ 'data_size': len(png_data),
+ 'data': png_data
+})
+
+img1 = lv.img(lv.scr_act())
+img1.set_src(img_cogwheel_argb)
+img1.align(lv.ALIGN.CENTER, 0, -20)
+img1.set_size(200, 200)
+
+img2 = lv.img(lv.scr_act())
+img2.set_src(lv.SYMBOL.OK + "Accept")
+img2.align_to(img1, lv.ALIGN.OUT_BOTTOM_MID, 0, 20)
diff --git a/lib/lvgl/examples/widgets/img/lv_example_img_2.c b/lib/lvgl/examples/widgets/img/lv_example_img_2.c
new file mode 100644
index 00000000..698ab908
--- /dev/null
+++ b/lib/lvgl/examples/widgets/img/lv_example_img_2.c
@@ -0,0 +1,64 @@
+#include "../../lv_examples.h"
+#if LV_USE_IMG && LV_USE_SLIDER && LV_BUILD_EXAMPLES
+
+static lv_obj_t * create_slider(lv_color_t color);
+static void slider_event_cb(lv_event_t * e);
+
+static lv_obj_t * red_slider, * green_slider, * blue_slider, * intense_slider;
+static lv_obj_t * img1;
+
+
+/**
+ * Demonstrate runtime image re-coloring
+ */
+void lv_example_img_2(void)
+{
+ /*Create 4 sliders to adjust RGB color and re-color intensity*/
+ red_slider = create_slider(lv_palette_main(LV_PALETTE_RED));
+ green_slider = create_slider(lv_palette_main(LV_PALETTE_GREEN));
+ blue_slider = create_slider(lv_palette_main(LV_PALETTE_BLUE));
+ intense_slider = create_slider(lv_palette_main(LV_PALETTE_GREY));
+
+ lv_slider_set_value(red_slider, LV_OPA_20, LV_ANIM_OFF);
+ lv_slider_set_value(green_slider, LV_OPA_90, LV_ANIM_OFF);
+ lv_slider_set_value(blue_slider, LV_OPA_60, LV_ANIM_OFF);
+ lv_slider_set_value(intense_slider, LV_OPA_50, LV_ANIM_OFF);
+
+ lv_obj_align(red_slider, LV_ALIGN_LEFT_MID, 25, 0);
+ lv_obj_align_to(green_slider, red_slider, LV_ALIGN_OUT_RIGHT_MID, 25, 0);
+ lv_obj_align_to(blue_slider, green_slider, LV_ALIGN_OUT_RIGHT_MID, 25, 0);
+ lv_obj_align_to(intense_slider, blue_slider, LV_ALIGN_OUT_RIGHT_MID, 25, 0);
+
+ /*Now create the actual image*/
+ LV_IMG_DECLARE(img_cogwheel_argb)
+ img1 = lv_img_create(lv_scr_act());
+ lv_img_set_src(img1, &img_cogwheel_argb);
+ lv_obj_align(img1, LV_ALIGN_RIGHT_MID, -20, 0);
+
+ lv_event_send(intense_slider, LV_EVENT_VALUE_CHANGED, NULL);
+}
+
+static void slider_event_cb(lv_event_t * e)
+{
+ LV_UNUSED(e);
+
+ /*Recolor the image based on the sliders' values*/
+ lv_color_t color = lv_color_make(lv_slider_get_value(red_slider), lv_slider_get_value(green_slider),
+ lv_slider_get_value(blue_slider));
+ lv_opa_t intense = lv_slider_get_value(intense_slider);
+ lv_obj_set_style_img_recolor_opa(img1, intense, 0);
+ lv_obj_set_style_img_recolor(img1, color, 0);
+}
+
+static lv_obj_t * create_slider(lv_color_t color)
+{
+ lv_obj_t * slider = lv_slider_create(lv_scr_act());
+ lv_slider_set_range(slider, 0, 255);
+ lv_obj_set_size(slider, 10, 200);
+ lv_obj_set_style_bg_color(slider, color, LV_PART_KNOB);
+ lv_obj_set_style_bg_color(slider, lv_color_darken(color, LV_OPA_40), LV_PART_INDICATOR);
+ lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
+ return slider;
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/img/lv_example_img_2.py b/lib/lvgl/examples/widgets/img/lv_example_img_2.py
new file mode 100644
index 00000000..7660dea0
--- /dev/null
+++ b/lib/lvgl/examples/widgets/img/lv_example_img_2.py
@@ -0,0 +1,70 @@
+#!/opt/bin/lv_micropython -i
+import usys as sys
+import lvgl as lv
+import display_driver
+from imagetools import get_png_info, open_png
+
+# Register PNG image decoder
+decoder = lv.img.decoder_create()
+decoder.info_cb = get_png_info
+decoder.open_cb = open_png
+
+# Create an image from the png file
+try:
+ with open('../../assets/img_cogwheel_argb.png','rb') as f:
+ png_data = f.read()
+except:
+ print("Could not find img_cogwheel_argb.png")
+ sys.exit()
+
+img_cogwheel_argb = lv.img_dsc_t({
+ 'data_size': len(png_data),
+ 'data': png_data
+})
+
+def create_slider(color):
+ slider = lv.slider(lv.scr_act())
+ slider.set_range(0, 255)
+ slider.set_size(10, 200)
+ slider.set_style_bg_color(color, lv.PART.KNOB)
+ slider.set_style_bg_color(color.color_darken(lv.OPA._40), lv.PART.INDICATOR)
+ slider.add_event_cb(slider_event_cb, lv.EVENT.VALUE_CHANGED, None)
+ return slider
+
+def slider_event_cb(e):
+ # Recolor the image based on the sliders' values
+ color = lv.color_make(red_slider.get_value(), green_slider.get_value(), blue_slider.get_value())
+ intense = intense_slider.get_value()
+ img1.set_style_img_recolor_opa(intense, 0)
+ img1.set_style_img_recolor(color, 0)
+
+#
+# Demonstrate runtime image re-coloring
+#
+# Create 4 sliders to adjust RGB color and re-color intensity
+red_slider = create_slider(lv.palette_main(lv.PALETTE.RED))
+green_slider = create_slider(lv.palette_main(lv.PALETTE.GREEN))
+blue_slider = create_slider(lv.palette_main(lv.PALETTE.BLUE))
+intense_slider = create_slider(lv.palette_main(lv.PALETTE.GREY))
+
+red_slider.set_value(lv.OPA._20, lv.ANIM.OFF)
+green_slider.set_value(lv.OPA._90, lv.ANIM.OFF)
+blue_slider.set_value(lv.OPA._60, lv.ANIM.OFF)
+intense_slider.set_value(lv.OPA._50, lv.ANIM.OFF)
+
+red_slider.align(lv.ALIGN.LEFT_MID, 25, 0)
+green_slider.align_to(red_slider, lv.ALIGN.OUT_RIGHT_MID, 25, 0)
+blue_slider.align_to(green_slider, lv.ALIGN.OUT_RIGHT_MID, 25, 0)
+intense_slider.align_to(blue_slider, lv.ALIGN.OUT_RIGHT_MID, 25, 0)
+
+# Now create the actual image
+img1 = lv.img(lv.scr_act())
+img1.set_src(img_cogwheel_argb)
+img1.align(lv.ALIGN.RIGHT_MID, -20, 0)
+
+lv.event_send(intense_slider, lv.EVENT.VALUE_CHANGED, None)
+
+
+
+
+
diff --git a/lib/lvgl/examples/widgets/img/lv_example_img_3.c b/lib/lvgl/examples/widgets/img/lv_example_img_3.c
new file mode 100644
index 00000000..aa5b5f3b
--- /dev/null
+++ b/lib/lvgl/examples/widgets/img/lv_example_img_3.c
@@ -0,0 +1,43 @@
+#include "../../lv_examples.h"
+#if LV_USE_IMG && LV_BUILD_EXAMPLES
+
+static void set_angle(void * img, int32_t v)
+{
+ lv_img_set_angle(img, v);
+}
+
+static void set_zoom(void * img, int32_t v)
+{
+ lv_img_set_zoom(img, v);
+}
+
+
+/**
+ * Show transformations (zoom and rotation) using a pivot point.
+ */
+void lv_example_img_3(void)
+{
+ LV_IMG_DECLARE(img_cogwheel_argb);
+
+ /*Now create the actual image*/
+ lv_obj_t * img = lv_img_create(lv_scr_act());
+ lv_img_set_src(img, &img_cogwheel_argb);
+ lv_obj_align(img, LV_ALIGN_CENTER, 50, 50);
+ lv_img_set_pivot(img, 0, 0); /*Rotate around the top left corner*/
+
+ lv_anim_t a;
+ lv_anim_init(&a);
+ lv_anim_set_var(&a, img);
+ lv_anim_set_exec_cb(&a, set_angle);
+ lv_anim_set_values(&a, 0, 3600);
+ lv_anim_set_time(&a, 5000);
+ lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
+ lv_anim_start(&a);
+
+ lv_anim_set_exec_cb(&a, set_zoom);
+ lv_anim_set_values(&a, 128, 256);
+ lv_anim_set_playback_time(&a, 3000);
+ lv_anim_start(&a);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/img/lv_example_img_3.py b/lib/lvgl/examples/widgets/img/lv_example_img_3.py
new file mode 100644
index 00000000..07f222dc
--- /dev/null
+++ b/lib/lvgl/examples/widgets/img/lv_example_img_3.py
@@ -0,0 +1,61 @@
+#!/opt/bin/lv_micropython -i
+import usys as sys
+import lvgl as lv
+import display_driver
+from imagetools import get_png_info, open_png
+
+# Register PNG image decoder
+decoder = lv.img.decoder_create()
+decoder.info_cb = get_png_info
+decoder.open_cb = open_png
+
+# Create an image from the png file
+try:
+ with open('../../assets/img_cogwheel_argb.png','rb') as f:
+ png_data = f.read()
+except:
+ print("Could not find img_cogwheel_argb.png")
+ sys.exit()
+
+img_cogwheel_argb = lv.img_dsc_t({
+ 'data_size': len(png_data),
+ 'data': png_data
+})
+
+def set_angle(img, v):
+ img.set_angle(v)
+
+def set_zoom(img, v):
+ img.set_zoom(v)
+
+
+#
+# Show transformations (zoom and rotation) using a pivot point.
+#
+
+# Now create the actual image
+img = lv.img(lv.scr_act())
+img.set_src(img_cogwheel_argb)
+img.align(lv.ALIGN.CENTER, 50, 50)
+img.set_pivot(0, 0) # Rotate around the top left corner
+
+a1 = lv.anim_t()
+a1.init()
+a1.set_var(img)
+a1.set_custom_exec_cb(lambda a,val: set_angle(img,val))
+a1.set_values(0, 3600)
+a1.set_time(5000)
+a1.set_repeat_count(lv.ANIM_REPEAT.INFINITE)
+lv.anim_t.start(a1)
+
+a2 = lv.anim_t()
+a2.init()
+a2.set_var(img)
+a2.set_custom_exec_cb(lambda a,val: set_zoom(img,val))
+a2.set_values(128, 256)
+a2.set_time(5000)
+a2.set_playback_time(3000)
+a2.set_repeat_count(lv.ANIM_REPEAT.INFINITE)
+lv.anim_t.start(a2)
+
+
diff --git a/lib/lvgl/examples/widgets/img/lv_example_img_4.c b/lib/lvgl/examples/widgets/img/lv_example_img_4.c
new file mode 100644
index 00000000..3abc021f
--- /dev/null
+++ b/lib/lvgl/examples/widgets/img/lv_example_img_4.c
@@ -0,0 +1,41 @@
+#include "../../lv_examples.h"
+#if LV_USE_IMG && LV_BUILD_EXAMPLES
+
+static void ofs_y_anim(void * img, int32_t v)
+{
+ lv_img_set_offset_y(img, v);
+}
+
+/**
+ * Image styling and offset
+ */
+void lv_example_img_4(void)
+{
+ LV_IMG_DECLARE(img_skew_strip);
+
+ static lv_style_t style;
+ lv_style_init(&style);
+ lv_style_set_bg_color(&style, lv_palette_main(LV_PALETTE_YELLOW));
+ lv_style_set_bg_opa(&style, LV_OPA_COVER);
+ lv_style_set_img_recolor_opa(&style, LV_OPA_COVER);
+ lv_style_set_img_recolor(&style, lv_color_black());
+
+ lv_obj_t * img = lv_img_create(lv_scr_act());
+ lv_obj_add_style(img, &style, 0);
+ lv_img_set_src(img, &img_skew_strip);
+ lv_obj_set_size(img, 150, 100);
+ lv_obj_center(img);
+
+ lv_anim_t a;
+ lv_anim_init(&a);
+ lv_anim_set_var(&a, img);
+ lv_anim_set_exec_cb(&a, ofs_y_anim);
+ lv_anim_set_values(&a, 0, 100);
+ lv_anim_set_time(&a, 3000);
+ lv_anim_set_playback_time(&a, 500);
+ lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
+ lv_anim_start(&a);
+
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/img/lv_example_img_4.py b/lib/lvgl/examples/widgets/img/lv_example_img_4.py
new file mode 100644
index 00000000..37b24a0b
--- /dev/null
+++ b/lib/lvgl/examples/widgets/img/lv_example_img_4.py
@@ -0,0 +1,51 @@
+from imagetools import get_png_info, open_png
+
+def ofs_y_anim(img, v):
+ img.set_offset_y(v)
+ # print(img,v)
+
+# Register PNG image decoder
+decoder = lv.img.decoder_create()
+decoder.info_cb = get_png_info
+decoder.open_cb = open_png
+
+# Create an image from the png file
+try:
+ with open('../../assets/img_skew_strip.png','rb') as f:
+ png_data = f.read()
+except:
+ print("Could not find img_skew_strip.png")
+ sys.exit()
+
+img_skew_strip = lv.img_dsc_t({
+ 'data_size': len(png_data),
+ 'data': png_data
+})
+
+#
+# Image styling and offset
+#
+
+style = lv.style_t()
+style.init()
+style.set_bg_color(lv.palette_main(lv.PALETTE.YELLOW))
+style.set_bg_opa(lv.OPA.COVER)
+style.set_img_recolor_opa(lv.OPA.COVER)
+style.set_img_recolor(lv.color_black())
+
+img = lv.img(lv.scr_act())
+img.add_style(style, 0)
+img.set_src(img_skew_strip)
+img.set_size(150, 100)
+img.center()
+
+a = lv.anim_t()
+a.init()
+a.set_var(img)
+a.set_values(0, 100)
+a.set_time(3000)
+a.set_playback_time(500)
+a.set_repeat_count(lv.ANIM_REPEAT.INFINITE)
+a.set_custom_exec_cb(lambda a,val: ofs_y_anim(img,val))
+lv.anim_t.start(a)
+
diff --git a/lib/lvgl/examples/widgets/imgbtn/index.rst b/lib/lvgl/examples/widgets/imgbtn/index.rst
new file mode 100644
index 00000000..7a55e01a
--- /dev/null
+++ b/lib/lvgl/examples/widgets/imgbtn/index.rst
@@ -0,0 +1,7 @@
+
+Simple Image button
+"""""""""""""""""""
+
+.. lv_example:: widgets/imgbtn/lv_example_imgbtn_1
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/imgbtn/lv_example_imgbtn_1.c b/lib/lvgl/examples/widgets/imgbtn/lv_example_imgbtn_1.c
new file mode 100644
index 00000000..4fcb62e4
--- /dev/null
+++ b/lib/lvgl/examples/widgets/imgbtn/lv_example_imgbtn_1.c
@@ -0,0 +1,41 @@
+#include "../../lv_examples.h"
+#if LV_USE_IMGBTN && LV_BUILD_EXAMPLES
+
+void lv_example_imgbtn_1(void)
+{
+ LV_IMG_DECLARE(imgbtn_left);
+ LV_IMG_DECLARE(imgbtn_right);
+ LV_IMG_DECLARE(imgbtn_mid);
+
+ /*Create a transition animation on width transformation and recolor.*/
+ static lv_style_prop_t tr_prop[] = {LV_STYLE_TRANSFORM_WIDTH, LV_STYLE_IMG_RECOLOR_OPA, 0};
+ static lv_style_transition_dsc_t tr;
+ lv_style_transition_dsc_init(&tr, tr_prop, lv_anim_path_linear, 200, 0, NULL);
+
+ static lv_style_t style_def;
+ lv_style_init(&style_def);
+ lv_style_set_text_color(&style_def, lv_color_white());
+ lv_style_set_transition(&style_def, &tr);
+
+ /*Darken the button when pressed and make it wider*/
+ static lv_style_t style_pr;
+ lv_style_init(&style_pr);
+ lv_style_set_img_recolor_opa(&style_pr, LV_OPA_30);
+ lv_style_set_img_recolor(&style_pr, lv_color_black());
+ lv_style_set_transform_width(&style_pr, 20);
+
+ /*Create an image button*/
+ lv_obj_t * imgbtn1 = lv_imgbtn_create(lv_scr_act());
+ lv_imgbtn_set_src(imgbtn1, LV_IMGBTN_STATE_RELEASED, &imgbtn_left, &imgbtn_mid, &imgbtn_right);
+ lv_obj_add_style(imgbtn1, &style_def, 0);
+ lv_obj_add_style(imgbtn1, &style_pr, LV_STATE_PRESSED);
+
+ lv_obj_align(imgbtn1, LV_ALIGN_CENTER, 0, 0);
+
+ /*Create a label on the image button*/
+ lv_obj_t * label = lv_label_create(imgbtn1);
+ lv_label_set_text(label, "Button");
+ lv_obj_align(label, LV_ALIGN_CENTER, 0, -4);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/imgbtn/lv_example_imgbtn_1.py b/lib/lvgl/examples/widgets/imgbtn/lv_example_imgbtn_1.py
new file mode 100644
index 00000000..23410559
--- /dev/null
+++ b/lib/lvgl/examples/widgets/imgbtn/lv_example_imgbtn_1.py
@@ -0,0 +1,74 @@
+from imagetools import get_png_info, open_png
+
+# Register PNG image decoder
+decoder = lv.img.decoder_create()
+decoder.info_cb = get_png_info
+decoder.open_cb = open_png
+
+# Create an image from the png file
+try:
+ with open('../../assets/imgbtn_left.png','rb') as f:
+ imgbtn_left_data = f.read()
+except:
+ print("Could not find imgbtn_left.png")
+ sys.exit()
+
+imgbtn_left_dsc = lv.img_dsc_t({
+ 'data_size': len(imgbtn_left_data),
+ 'data': imgbtn_left_data
+})
+
+try:
+ with open('../../assets/imgbtn_mid.png','rb') as f:
+ imgbtn_mid_data = f.read()
+except:
+ print("Could not find imgbtn_mid.png")
+ sys.exit()
+
+imgbtn_mid_dsc = lv.img_dsc_t({
+ 'data_size': len(imgbtn_mid_data),
+ 'data': imgbtn_mid_data
+})
+
+try:
+ with open('../../assets/imgbtn_right.png','rb') as f:
+ imgbtn_right_data = f.read()
+except:
+ print("Could not find imgbtn_right.png")
+ sys.exit()
+
+imgbtn_right_dsc = lv.img_dsc_t({
+ 'data_size': len(imgbtn_right_data),
+ 'data': imgbtn_right_data
+})
+
+# Create a transition animation on width transformation and recolor.
+tr_prop = [lv.STYLE.TRANSFORM_WIDTH, lv.STYLE.IMG_RECOLOR_OPA, 0]
+tr = lv.style_transition_dsc_t()
+tr.init(tr_prop, lv.anim_t.path_linear, 200, 0, None)
+
+style_def = lv.style_t()
+style_def.init()
+style_def.set_text_color(lv.color_white())
+style_def.set_transition(tr)
+
+# Darken the button when pressed and make it wider
+style_pr = lv.style_t()
+style_pr.init()
+style_pr.set_img_recolor_opa(lv.OPA._30)
+style_pr.set_img_recolor(lv.color_black())
+style_pr.set_transform_width(20)
+
+# Create an image button
+imgbtn1 = lv.imgbtn(lv.scr_act())
+imgbtn1.set_src(lv.imgbtn.STATE.RELEASED, imgbtn_left_dsc, imgbtn_mid_dsc, imgbtn_right_dsc)
+imgbtn1.add_style(style_def, 0)
+imgbtn1.add_style(style_pr, lv.STATE.PRESSED)
+
+imgbtn1.align(lv.ALIGN.CENTER, 0, 0)
+
+# Create a label on the image button
+label = lv.label(imgbtn1)
+label.set_text("Button")
+label.align(lv.ALIGN.CENTER, 0, -4)
+
diff --git a/lib/lvgl/examples/widgets/keyboard/index.rst b/lib/lvgl/examples/widgets/keyboard/index.rst
new file mode 100644
index 00000000..7c54e052
--- /dev/null
+++ b/lib/lvgl/examples/widgets/keyboard/index.rst
@@ -0,0 +1,7 @@
+
+Keyboard with text area
+"""""""""""""""""""""""
+
+.. lv_example:: widgets/keyboard/lv_example_keyboard_1
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/keyboard/lv_example_keyboard_1.c b/lib/lvgl/examples/widgets/keyboard/lv_example_keyboard_1.c
new file mode 100644
index 00000000..710098fe
--- /dev/null
+++ b/lib/lvgl/examples/widgets/keyboard/lv_example_keyboard_1.c
@@ -0,0 +1,40 @@
+#include "../../lv_examples.h"
+#if LV_USE_KEYBOARD && LV_BUILD_EXAMPLES
+
+static void ta_event_cb(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * ta = lv_event_get_target(e);
+ lv_obj_t * kb = lv_event_get_user_data(e);
+ if(code == LV_EVENT_FOCUSED) {
+ lv_keyboard_set_textarea(kb, ta);
+ lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN);
+ }
+
+ if(code == LV_EVENT_DEFOCUSED) {
+ lv_keyboard_set_textarea(kb, NULL);
+ lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
+ }
+}
+
+void lv_example_keyboard_1(void)
+{
+ /*Create a keyboard to use it with an of the text areas*/
+ lv_obj_t * kb = lv_keyboard_create(lv_scr_act());
+
+ /*Create a text area. The keyboard will write here*/
+ lv_obj_t * ta;
+ ta = lv_textarea_create(lv_scr_act());
+ lv_obj_align(ta, LV_ALIGN_TOP_LEFT, 10, 10);
+ lv_obj_add_event_cb(ta, ta_event_cb, LV_EVENT_ALL, kb);
+ lv_textarea_set_placeholder_text(ta, "Hello");
+ lv_obj_set_size(ta, 140, 80);
+
+ ta = lv_textarea_create(lv_scr_act());
+ lv_obj_align(ta, LV_ALIGN_TOP_RIGHT, -10, 10);
+ lv_obj_add_event_cb(ta, ta_event_cb, LV_EVENT_ALL, kb);
+ lv_obj_set_size(ta, 140, 80);
+
+ lv_keyboard_set_textarea(kb, ta);
+}
+#endif
diff --git a/lib/lvgl/examples/widgets/keyboard/lv_example_keyboard_1.py b/lib/lvgl/examples/widgets/keyboard/lv_example_keyboard_1.py
new file mode 100644
index 00000000..7b7591f7
--- /dev/null
+++ b/lib/lvgl/examples/widgets/keyboard/lv_example_keyboard_1.py
@@ -0,0 +1,28 @@
+def ta_event_cb(e,kb):
+ code = e.get_code()
+ ta = e.get_target()
+ if code == lv.EVENT.FOCUSED:
+ kb.set_textarea(ta)
+ kb.clear_flag(lv.obj.FLAG.HIDDEN)
+
+ if code == lv.EVENT.DEFOCUSED:
+ kb.set_textarea(None)
+ kb.add_flag(lv.obj.FLAG.HIDDEN)
+
+# Create a keyboard to use it with one of the text areas
+kb = lv.keyboard(lv.scr_act())
+
+# Create a text area. The keyboard will write here
+ta = lv.textarea(lv.scr_act())
+ta.set_width(200)
+ta.align(lv.ALIGN.TOP_LEFT, 10, 10)
+ta.add_event_cb(lambda e: ta_event_cb(e,kb), lv.EVENT.ALL, None)
+ta.set_placeholder_text("Hello")
+
+ta = lv.textarea(lv.scr_act())
+ta.set_width(200)
+ta.align(lv.ALIGN.TOP_RIGHT, -10, 10)
+ta.add_event_cb(lambda e: ta_event_cb(e,kb), lv.EVENT.ALL, None)
+
+kb.set_textarea(ta)
+
diff --git a/lib/lvgl/examples/widgets/label/index.rst b/lib/lvgl/examples/widgets/label/index.rst
new file mode 100644
index 00000000..b2b56478
--- /dev/null
+++ b/lib/lvgl/examples/widgets/label/index.rst
@@ -0,0 +1,31 @@
+
+Line wrap, recoloring and scrolling
+"""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/label/lv_example_label_1
+ :language: c
+
+Text shadow
+""""""""""""
+
+.. lv_example:: widgets/label/lv_example_label_2
+ :language: c
+
+Show LTR, RTL and Chinese texts
+""""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/label/lv_example_label_3
+ :language: c
+
+Draw label with gradient color
+""""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/label/lv_example_label_4
+ :language: c
+
+Customize circular scrolling animation
+""""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/label/lv_example_label_5
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/label/lv_example_label_1.c b/lib/lvgl/examples/widgets/label/lv_example_label_1.c
new file mode 100644
index 00000000..886cd4a7
--- /dev/null
+++ b/lib/lvgl/examples/widgets/label/lv_example_label_1.c
@@ -0,0 +1,25 @@
+#include "../../lv_examples.h"
+#if LV_USE_LABEL && LV_BUILD_EXAMPLES
+
+/**
+ * Show line wrap, re-color, line align and text scrolling.
+ */
+void lv_example_label_1(void)
+{
+ lv_obj_t * label1 = lv_label_create(lv_scr_act());
+ lv_label_set_long_mode(label1, LV_LABEL_LONG_WRAP); /*Break the long lines*/
+ lv_label_set_recolor(label1, true); /*Enable re-coloring by commands in the text*/
+ lv_label_set_text(label1, "#0000ff Re-color# #ff00ff words# #ff0000 of a# label, align the lines to the center "
+ "and wrap long text automatically.");
+ lv_obj_set_width(label1, 150); /*Set smaller width to make the lines wrap*/
+ lv_obj_set_style_text_align(label1, LV_TEXT_ALIGN_CENTER, 0);
+ lv_obj_align(label1, LV_ALIGN_CENTER, 0, -40);
+
+ lv_obj_t * label2 = lv_label_create(lv_scr_act());
+ lv_label_set_long_mode(label2, LV_LABEL_LONG_SCROLL_CIRCULAR); /*Circular scroll*/
+ lv_obj_set_width(label2, 150);
+ lv_label_set_text(label2, "It is a circularly scrolling text. ");
+ lv_obj_align(label2, LV_ALIGN_CENTER, 0, 40);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/label/lv_example_label_1.py b/lib/lvgl/examples/widgets/label/lv_example_label_1.py
new file mode 100644
index 00000000..f2fa9114
--- /dev/null
+++ b/lib/lvgl/examples/widgets/label/lv_example_label_1.py
@@ -0,0 +1,19 @@
+#
+# Show line wrap, re-color, line align and text scrolling.
+#
+label1 = lv.label(lv.scr_act())
+label1.set_long_mode(lv.label.LONG.WRAP) # Break the long lines*/
+label1.set_recolor(True) # Enable re-coloring by commands in the text
+label1.set_text("#0000ff Re-color# #ff00ff words# #ff0000 of a# label, align the lines to the center"
+ "and wrap long text automatically.")
+label1.set_width(150) # Set smaller width to make the lines wrap
+label1.set_style_text_align(lv.ALIGN.CENTER, 0)
+label1.align(lv.ALIGN.CENTER, 0, -40)
+
+
+label2 = lv.label(lv.scr_act())
+label2.set_long_mode(lv.label.LONG.SCROLL_CIRCULAR) # Circular scroll
+label2.set_width(150)
+label2.set_text("It is a circularly scrolling text. ")
+label2.align(lv.ALIGN.CENTER, 0, 40)
+
diff --git a/lib/lvgl/examples/widgets/label/lv_example_label_2.c b/lib/lvgl/examples/widgets/label/lv_example_label_2.c
new file mode 100644
index 00000000..0b605cf2
--- /dev/null
+++ b/lib/lvgl/examples/widgets/label/lv_example_label_2.c
@@ -0,0 +1,36 @@
+#include "../../lv_examples.h"
+#if LV_USE_LABEL && LV_BUILD_EXAMPLES
+
+/**
+ * Create a fake text shadow
+ */
+void lv_example_label_2(void)
+{
+ /*Create a style for the shadow*/
+ static lv_style_t style_shadow;
+ lv_style_init(&style_shadow);
+ lv_style_set_text_opa(&style_shadow, LV_OPA_30);
+ lv_style_set_text_color(&style_shadow, lv_color_black());
+
+ /*Create a label for the shadow first (it's in the background)*/
+ lv_obj_t * shadow_label = lv_label_create(lv_scr_act());
+ lv_obj_add_style(shadow_label, &style_shadow, 0);
+
+ /*Create the main label*/
+ lv_obj_t * main_label = lv_label_create(lv_scr_act());
+ lv_label_set_text(main_label, "A simple method to create\n"
+ "shadows on a text.\n"
+ "It even works with\n\n"
+ "newlines and spaces.");
+
+ /*Set the same text for the shadow label*/
+ lv_label_set_text(shadow_label, lv_label_get_text(main_label));
+
+ /*Position the main label*/
+ lv_obj_align(main_label, LV_ALIGN_CENTER, 0, 0);
+
+ /*Shift the second label down and to the right by 2 pixel*/
+ lv_obj_align_to(shadow_label, main_label, LV_ALIGN_TOP_LEFT, 2, 2);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/label/lv_example_label_2.py b/lib/lvgl/examples/widgets/label/lv_example_label_2.py
new file mode 100644
index 00000000..d252f256
--- /dev/null
+++ b/lib/lvgl/examples/widgets/label/lv_example_label_2.py
@@ -0,0 +1,30 @@
+#
+# Create a fake text shadow
+#
+
+# Create a style for the shadow
+style_shadow = lv.style_t()
+style_shadow.init()
+style_shadow.set_text_opa(lv.OPA._30)
+style_shadow.set_text_color(lv.color_black())
+
+# Create a label for the shadow first (it's in the background)
+shadow_label = lv.label(lv.scr_act())
+shadow_label.add_style(style_shadow, 0)
+
+# Create the main label
+main_label = lv.label(lv.scr_act())
+main_label.set_text("A simple method to create\n"
+ "shadows on a text.\n"
+ "It even works with\n\n"
+ "newlines and spaces.")
+
+# Set the same text for the shadow label
+shadow_label.set_text(lv.label.get_text(main_label))
+
+# Position the main label
+main_label.align(lv.ALIGN.CENTER, 0, 0)
+
+# Shift the second label down and to the right by 2 pixel
+shadow_label.align_to(main_label, lv.ALIGN.TOP_LEFT, 2, 2)
+
diff --git a/lib/lvgl/examples/widgets/label/lv_example_label_3.c b/lib/lvgl/examples/widgets/label/lv_example_label_3.c
new file mode 100644
index 00000000..680d88fe
--- /dev/null
+++ b/lib/lvgl/examples/widgets/label/lv_example_label_3.c
@@ -0,0 +1,31 @@
+#include "../../lv_examples.h"
+#if LV_USE_LABEL && LV_BUILD_EXAMPLES && LV_FONT_DEJAVU_16_PERSIAN_HEBREW && LV_FONT_SIMSUN_16_CJK && LV_USE_BIDI
+
+/**
+ * Show mixed LTR, RTL and Chinese label
+ */
+void lv_example_label_3(void)
+{
+ lv_obj_t * ltr_label = lv_label_create(lv_scr_act());
+ lv_label_set_text(ltr_label, "In modern terminology, a microcontroller is similar to a system on a chip (SoC).");
+ lv_obj_set_style_text_font(ltr_label, &lv_font_montserrat_16, 0);
+ lv_obj_set_width(ltr_label, 310);
+ lv_obj_align(ltr_label, LV_ALIGN_TOP_LEFT, 5, 5);
+
+ lv_obj_t * rtl_label = lv_label_create(lv_scr_act());
+ lv_label_set_text(rtl_label,
+ "מעבד, או בשמו המלא יחידת עיבוד מרכזית (באנגלית: CPU - Central Processing Unit).");
+ lv_obj_set_style_base_dir(rtl_label, LV_BASE_DIR_RTL, 0);
+ lv_obj_set_style_text_font(rtl_label, &lv_font_dejavu_16_persian_hebrew, 0);
+ lv_obj_set_width(rtl_label, 310);
+ lv_obj_align(rtl_label, LV_ALIGN_LEFT_MID, 5, 0);
+
+ lv_obj_t * cz_label = lv_label_create(lv_scr_act());
+ lv_label_set_text(cz_label,
+ "嵌入式系统(Embedded System),\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。");
+ lv_obj_set_style_text_font(cz_label, &lv_font_simsun_16_cjk, 0);
+ lv_obj_set_width(cz_label, 310);
+ lv_obj_align(cz_label, LV_ALIGN_BOTTOM_LEFT, 5, -5);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/label/lv_example_label_3.py b/lib/lvgl/examples/widgets/label/lv_example_label_3.py
new file mode 100644
index 00000000..12c9034a
--- /dev/null
+++ b/lib/lvgl/examples/widgets/label/lv_example_label_3.py
@@ -0,0 +1,36 @@
+import fs_driver
+#
+# Show mixed LTR, RTL and Chinese label
+#
+
+ltr_label = lv.label(lv.scr_act())
+ltr_label.set_text("In modern terminology, a microcontroller is similar to a system on a chip (SoC).")
+# ltr_label.set_style_text_font(ltr_label, &lv_font_montserrat_16, 0);
+
+fs_drv = lv.fs_drv_t()
+fs_driver.fs_register(fs_drv, 'S')
+
+try:
+ ltr_label.set_style_text_font(ltr_label, lv.font_montserrat_16, 0)
+except:
+ font_montserrat_16 = lv.font_load("S:../../assets/font/montserrat-16.fnt")
+ ltr_label.set_style_text_font(font_montserrat_16, 0)
+
+ltr_label.set_width(310)
+ltr_label.align(lv.ALIGN.TOP_LEFT, 5, 5)
+
+rtl_label = lv.label(lv.scr_act())
+rtl_label.set_text("מעבד, או בשמו המלא יחידת עיבוד מרכזית (באנגלית: CPU - Central Processing Unit).")
+rtl_label.set_style_base_dir(lv.BASE_DIR.RTL, 0)
+rtl_label.set_style_text_font(lv.font_dejavu_16_persian_hebrew, 0)
+rtl_label.set_width(310)
+rtl_label.align(lv.ALIGN.LEFT_MID, 5, 0)
+
+font_simsun_16_cjk = lv.font_load("S:../../assets/font/lv_font_simsun_16_cjk.fnt")
+
+cz_label = lv.label(lv.scr_act())
+cz_label.set_style_text_font(font_simsun_16_cjk, 0)
+cz_label.set_text("嵌入式系统(Embedded System),\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。")
+cz_label.set_width(310)
+cz_label.align(lv.ALIGN.BOTTOM_LEFT, 5, -5)
+
diff --git a/lib/lvgl/examples/widgets/label/lv_example_label_4.c b/lib/lvgl/examples/widgets/label/lv_example_label_4.c
new file mode 100644
index 00000000..68b456af
--- /dev/null
+++ b/lib/lvgl/examples/widgets/label/lv_example_label_4.c
@@ -0,0 +1,63 @@
+#include "../../lv_examples.h"
+#if LV_USE_LABEL && LV_USE_CANVAS && LV_BUILD_EXAMPLES && LV_DRAW_COMPLEX
+
+#define MASK_WIDTH 100
+#define MASK_HEIGHT 45
+
+static void add_mask_event_cb(lv_event_t * e)
+{
+ static lv_draw_mask_map_param_t m;
+ static int16_t mask_id;
+
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+ lv_opa_t * mask_map = lv_event_get_user_data(e);
+ if(code == LV_EVENT_COVER_CHECK) {
+ lv_event_set_cover_res(e, LV_COVER_RES_MASKED);
+ }
+ else if(code == LV_EVENT_DRAW_MAIN_BEGIN) {
+ lv_draw_mask_map_init(&m, &obj->coords, mask_map);
+ mask_id = lv_draw_mask_add(&m, NULL);
+
+ }
+ else if(code == LV_EVENT_DRAW_MAIN_END) {
+ lv_draw_mask_free_param(&m);
+ lv_draw_mask_remove_id(mask_id);
+ }
+}
+
+/**
+ * Draw label with gradient color
+ */
+void lv_example_label_4(void)
+{
+ /* Create the mask of a text by drawing it to a canvas*/
+ static lv_opa_t mask_map[MASK_WIDTH * MASK_HEIGHT];
+
+ /*Create a "8 bit alpha" canvas and clear it*/
+ lv_obj_t * canvas = lv_canvas_create(lv_scr_act());
+ lv_canvas_set_buffer(canvas, mask_map, MASK_WIDTH, MASK_HEIGHT, LV_IMG_CF_ALPHA_8BIT);
+ lv_canvas_fill_bg(canvas, lv_color_black(), LV_OPA_TRANSP);
+
+ /*Draw a label to the canvas. The result "image" will be used as mask*/
+ lv_draw_label_dsc_t label_dsc;
+ lv_draw_label_dsc_init(&label_dsc);
+ label_dsc.color = lv_color_white();
+ label_dsc.align = LV_TEXT_ALIGN_CENTER;
+ lv_canvas_draw_text(canvas, 5, 5, MASK_WIDTH, &label_dsc, "Text with gradient");
+
+ /*The mask is reads the canvas is not required anymore*/
+ lv_obj_del(canvas);
+
+ /* Create an object from where the text will be masked out.
+ * Now it's a rectangle with a gradient but it could be an image too*/
+ lv_obj_t * grad = lv_obj_create(lv_scr_act());
+ lv_obj_set_size(grad, MASK_WIDTH, MASK_HEIGHT);
+ lv_obj_center(grad);
+ lv_obj_set_style_bg_color(grad, lv_color_hex(0xff0000), 0);
+ lv_obj_set_style_bg_grad_color(grad, lv_color_hex(0x0000ff), 0);
+ lv_obj_set_style_bg_grad_dir(grad, LV_GRAD_DIR_HOR, 0);
+ lv_obj_add_event_cb(grad, add_mask_event_cb, LV_EVENT_ALL, mask_map);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/label/lv_example_label_5.c b/lib/lvgl/examples/widgets/label/lv_example_label_5.c
new file mode 100644
index 00000000..c190df69
--- /dev/null
+++ b/lib/lvgl/examples/widgets/label/lv_example_label_5.c
@@ -0,0 +1,30 @@
+#include "../../lv_examples.h"
+#if LV_USE_LABEL && LV_BUILD_EXAMPLES
+
+/**
+ * Show customizing the circular scrolling animation of a label with `LV_LABEL_LONG_SCROLL_CIRCULAR`
+ * long mode.
+ */
+void lv_example_label_5(void)
+{
+ static lv_anim_t animation_template;
+ static lv_style_t label_style;
+
+ lv_anim_init(&animation_template);
+ lv_anim_set_delay(&animation_template, 1000); /*Wait 1 second to start the first scroll*/
+ lv_anim_set_repeat_delay(&animation_template,
+ 3000); /*Repeat the scroll 3 seconds after the label scrolls back to the initial position*/
+
+ /*Initialize the label style with the animation template*/
+ lv_style_init(&label_style);
+ lv_style_set_anim(&label_style, &animation_template);
+
+ lv_obj_t * label1 = lv_label_create(lv_scr_act());
+ lv_label_set_long_mode(label1, LV_LABEL_LONG_SCROLL_CIRCULAR); /*Circular scroll*/
+ lv_obj_set_width(label1, 150);
+ lv_label_set_text(label1, "It is a circularly scrolling text. ");
+ lv_obj_align(label1, LV_ALIGN_CENTER, 0, 40);
+ lv_obj_add_style(label1, &label_style, LV_STATE_DEFAULT); /*Add the style to the label*/
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/label/lv_example_label_5.py b/lib/lvgl/examples/widgets/label/lv_example_label_5.py
new file mode 100644
index 00000000..817d53e3
--- /dev/null
+++ b/lib/lvgl/examples/widgets/label/lv_example_label_5.py
@@ -0,0 +1,10 @@
+#
+# Show customizing the circular scrolling animation of a label with `LV_LABEL_LONG_SCROLL_CIRCULAR` long mode.
+#
+
+label1 = lv.label(lv.scr_act())
+label1.set_long_mode(lv.label.LONG.SCROLL_CIRCULAR) # Circular scroll
+label1.set_width(150)
+label1.set_text("It is a circularly scrolling text. ")
+label1.align(lv.ALIGN.CENTER, 0, 40)
+
diff --git a/lib/lvgl/examples/widgets/led/index.rst b/lib/lvgl/examples/widgets/led/index.rst
new file mode 100644
index 00000000..abfa810c
--- /dev/null
+++ b/lib/lvgl/examples/widgets/led/index.rst
@@ -0,0 +1,7 @@
+
+LED with custom style
+"""""""""""""""""""""
+
+.. lv_example:: widgets/led/lv_example_led_1
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/led/lv_example_led_1.c b/lib/lvgl/examples/widgets/led/lv_example_led_1.c
new file mode 100644
index 00000000..f06f31ef
--- /dev/null
+++ b/lib/lvgl/examples/widgets/led/lv_example_led_1.c
@@ -0,0 +1,26 @@
+#include "../../lv_examples.h"
+#if LV_USE_LED && LV_BUILD_EXAMPLES
+
+/**
+ * Create LED's with different brightness and color
+ */
+void lv_example_led_1(void)
+{
+ /*Create a LED and switch it OFF*/
+ lv_obj_t * led1 = lv_led_create(lv_scr_act());
+ lv_obj_align(led1, LV_ALIGN_CENTER, -80, 0);
+ lv_led_off(led1);
+
+ /*Copy the previous LED and set a brightness*/
+ lv_obj_t * led2 = lv_led_create(lv_scr_act());
+ lv_obj_align(led2, LV_ALIGN_CENTER, 0, 0);
+ lv_led_set_brightness(led2, 150);
+ lv_led_set_color(led2, lv_palette_main(LV_PALETTE_RED));
+
+ /*Copy the previous LED and switch it ON*/
+ lv_obj_t * led3 = lv_led_create(lv_scr_act());
+ lv_obj_align(led3, LV_ALIGN_CENTER, 80, 0);
+ lv_led_on(led3);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/led/lv_example_led_1.py b/lib/lvgl/examples/widgets/led/lv_example_led_1.py
new file mode 100644
index 00000000..5e1b1267
--- /dev/null
+++ b/lib/lvgl/examples/widgets/led/lv_example_led_1.py
@@ -0,0 +1,20 @@
+#
+# Create LED's with different brightness and color
+#
+
+# Create a LED and switch it OFF
+led1 = lv.led(lv.scr_act())
+led1.align(lv.ALIGN.CENTER, -80, 0)
+led1.off()
+
+# Copy the previous LED and set a brightness
+led2 = lv.led(lv.scr_act())
+led2.align(lv.ALIGN.CENTER, 0, 0)
+led2.set_brightness(150)
+led2.set_color(lv.palette_main(lv.PALETTE.RED))
+
+# Copy the previous LED and switch it ON
+led3 = lv.led(lv.scr_act())
+led3.align(lv.ALIGN.CENTER, 80, 0)
+led3.on()
+
diff --git a/lib/lvgl/examples/widgets/line/index.rst b/lib/lvgl/examples/widgets/line/index.rst
new file mode 100644
index 00000000..156359a7
--- /dev/null
+++ b/lib/lvgl/examples/widgets/line/index.rst
@@ -0,0 +1,7 @@
+
+Simple Line
+""""""""""""""""
+
+.. lv_example:: widgets/line/lv_example_line_1
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/line/lv_example_line_1.c b/lib/lvgl/examples/widgets/line/lv_example_line_1.c
new file mode 100644
index 00000000..9c120a29
--- /dev/null
+++ b/lib/lvgl/examples/widgets/line/lv_example_line_1.c
@@ -0,0 +1,24 @@
+#include "../../lv_examples.h"
+#if LV_USE_LINE && LV_BUILD_EXAMPLES
+
+void lv_example_line_1(void)
+{
+ /*Create an array for the points of the line*/
+ static lv_point_t line_points[] = { {5, 5}, {70, 70}, {120, 10}, {180, 60}, {240, 10} };
+
+ /*Create style*/
+ static lv_style_t style_line;
+ lv_style_init(&style_line);
+ lv_style_set_line_width(&style_line, 8);
+ lv_style_set_line_color(&style_line, lv_palette_main(LV_PALETTE_BLUE));
+ lv_style_set_line_rounded(&style_line, true);
+
+ /*Create a line and apply the new style*/
+ lv_obj_t * line1;
+ line1 = lv_line_create(lv_scr_act());
+ lv_line_set_points(line1, line_points, 5); /*Set the points*/
+ lv_obj_add_style(line1, &style_line, 0);
+ lv_obj_center(line1);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/line/lv_example_line_1.py b/lib/lvgl/examples/widgets/line/lv_example_line_1.py
new file mode 100644
index 00000000..3a5822ff
--- /dev/null
+++ b/lib/lvgl/examples/widgets/line/lv_example_line_1.py
@@ -0,0 +1,20 @@
+# Create an array for the points of the line
+line_points = [ {"x":5, "y":5},
+ {"x":70, "y":70},
+ {"x":120, "y":10},
+ {"x":180, "y":60},
+ {"x":240, "y":10}]
+
+# Create style
+style_line = lv.style_t()
+style_line.init()
+style_line.set_line_width(8)
+style_line.set_line_color(lv.palette_main(lv.PALETTE.BLUE))
+style_line.set_line_rounded(True)
+
+# Create a line and apply the new style
+line1 = lv.line(lv.scr_act())
+line1.set_points(line_points, 5) # Set the points
+line1.add_style(style_line, 0)
+line1.center()
+
diff --git a/lib/lvgl/examples/widgets/list/index.rst b/lib/lvgl/examples/widgets/list/index.rst
new file mode 100644
index 00000000..ca8a897d
--- /dev/null
+++ b/lib/lvgl/examples/widgets/list/index.rst
@@ -0,0 +1,13 @@
+
+Simple List
+""""""""""""""""
+
+.. lv_example:: widgets/list/lv_example_list_1
+ :language: c
+
+
+Sorting a List using up and down buttons
+""""""""""""""""
+
+.. lv_example:: widgets/list/lv_example_list_2
+ :language: c
diff --git a/lib/lvgl/examples/widgets/list/lv_example_list_1.c b/lib/lvgl/examples/widgets/list/lv_example_list_1.c
new file mode 100644
index 00000000..4e129f4c
--- /dev/null
+++ b/lib/lvgl/examples/widgets/list/lv_example_list_1.c
@@ -0,0 +1,53 @@
+#include "../../lv_examples.h"
+#if LV_USE_LIST && LV_BUILD_EXAMPLES
+static lv_obj_t * list1;
+
+static void event_handler(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+ if(code == LV_EVENT_CLICKED) {
+ LV_LOG_USER("Clicked: %s", lv_list_get_btn_text(list1, obj));
+ }
+}
+
+void lv_example_list_1(void)
+{
+ /*Create a list*/
+ list1 = lv_list_create(lv_scr_act());
+ lv_obj_set_size(list1, 180, 220);
+ lv_obj_center(list1);
+
+ /*Add buttons to the list*/
+ lv_obj_t * btn;
+
+ lv_list_add_text(list1, "File");
+ btn = lv_list_add_btn(list1, LV_SYMBOL_FILE, "New");
+ lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
+ btn = lv_list_add_btn(list1, LV_SYMBOL_DIRECTORY, "Open");
+ lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
+ btn = lv_list_add_btn(list1, LV_SYMBOL_SAVE, "Save");
+ lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
+ btn = lv_list_add_btn(list1, LV_SYMBOL_CLOSE, "Delete");
+ lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
+ btn = lv_list_add_btn(list1, LV_SYMBOL_EDIT, "Edit");
+ lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
+
+ lv_list_add_text(list1, "Connectivity");
+ btn = lv_list_add_btn(list1, LV_SYMBOL_BLUETOOTH, "Bluetooth");
+ lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
+ btn = lv_list_add_btn(list1, LV_SYMBOL_GPS, "Navigation");
+ lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
+ btn = lv_list_add_btn(list1, LV_SYMBOL_USB, "USB");
+ lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
+ btn = lv_list_add_btn(list1, LV_SYMBOL_BATTERY_FULL, "Battery");
+ lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
+
+ lv_list_add_text(list1, "Exit");
+ btn = lv_list_add_btn(list1, LV_SYMBOL_OK, "Apply");
+ lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
+ btn = lv_list_add_btn(list1, LV_SYMBOL_CLOSE, "Close");
+ lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/list/lv_example_list_1.py b/lib/lvgl/examples/widgets/list/lv_example_list_1.py
new file mode 100644
index 00000000..2bb83cc6
--- /dev/null
+++ b/lib/lvgl/examples/widgets/list/lv_example_list_1.py
@@ -0,0 +1,40 @@
+def event_handler(e):
+ code = e.get_code()
+ obj = e.get_target()
+ if code == lv.EVENT.CLICKED:
+ print("Clicked: list1." + list1.get_btn_text(obj))
+
+# Create a list
+list1 = lv.list(lv.scr_act())
+list1.set_size(180, 220)
+list1.center()
+
+# Add buttons to the list
+list1.add_text("File")
+btn_new = list1.add_btn(lv.SYMBOL.FILE, "New")
+btn_new.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_open = list1.add_btn(lv.SYMBOL.DIRECTORY, "Open")
+btn_open.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_save = list1.add_btn(lv.SYMBOL.SAVE, "Save")
+btn_save.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_delete = list1.add_btn(lv.SYMBOL.CLOSE, "Delete")
+btn_delete.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_edit = list1.add_btn(lv.SYMBOL.EDIT, "Edit")
+btn_edit.add_event_cb(event_handler,lv.EVENT.ALL, None)
+
+list1.add_text("Connectivity")
+btn_bluetooth = list1.add_btn(lv.SYMBOL.BLUETOOTH, "Bluetooth")
+btn_bluetooth.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_navig = list1.add_btn(lv.SYMBOL.GPS, "Navigation")
+btn_navig.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_USB = list1.add_btn(lv.SYMBOL.USB, "USB")
+btn_USB.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_battery = list1.add_btn(lv.SYMBOL.BATTERY_FULL, "Battery")
+btn_battery.add_event_cb(event_handler,lv.EVENT.ALL, None)
+
+list1.add_text("Exit")
+btn_apply = list1.add_btn(lv.SYMBOL.OK, "Apply")
+btn_apply.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_close = list1.add_btn(lv.SYMBOL.CLOSE, "Close")
+btn_close.add_event_cb(event_handler,lv.EVENT.ALL, None)
+
diff --git a/lib/lvgl/examples/widgets/list/lv_example_list_2.c b/lib/lvgl/examples/widgets/list/lv_example_list_2.c
new file mode 100644
index 00000000..0def918e
--- /dev/null
+++ b/lib/lvgl/examples/widgets/list/lv_example_list_2.c
@@ -0,0 +1,169 @@
+#include <stdlib.h>
+
+
+#include "../../lv_examples.h"
+#if LV_USE_LIST && LV_BUILD_EXAMPLES
+
+static lv_obj_t * list1;
+static lv_obj_t * list2;
+
+static lv_obj_t * currentButton = NULL;
+
+static void event_handler(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+ if(code == LV_EVENT_CLICKED) {
+ LV_LOG_USER("Clicked: %s", lv_list_get_btn_text(list1, obj));
+
+ if(currentButton == obj) {
+ currentButton = NULL;
+ }
+ else {
+ currentButton = obj;
+ }
+ lv_obj_t * parent = lv_obj_get_parent(obj);
+ uint32_t i;
+ for(i = 0; i < lv_obj_get_child_cnt(parent); i++) {
+ lv_obj_t * child = lv_obj_get_child(parent, i);
+ if(child == currentButton) {
+ lv_obj_add_state(child, LV_STATE_CHECKED);
+ }
+ else {
+ lv_obj_clear_state(child, LV_STATE_CHECKED);
+ }
+ }
+ }
+}
+
+static void event_handler_top(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ if(code == LV_EVENT_CLICKED) {
+ if(currentButton == NULL) return;
+ lv_obj_move_background(currentButton);
+ lv_obj_scroll_to_view(currentButton, LV_ANIM_ON);
+ }
+}
+
+static void event_handler_up(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ if((code == LV_EVENT_CLICKED) || (code == LV_EVENT_LONG_PRESSED_REPEAT)) {
+ if(currentButton == NULL) return;
+ uint32_t index = lv_obj_get_index(currentButton);
+ if(index <= 0) return;
+ lv_obj_move_to_index(currentButton, index - 1);
+ lv_obj_scroll_to_view(currentButton, LV_ANIM_ON);
+ }
+}
+
+static void event_handler_center(lv_event_t * e)
+{
+ const lv_event_code_t code = lv_event_get_code(e);
+ if((code == LV_EVENT_CLICKED) || (code == LV_EVENT_LONG_PRESSED_REPEAT)) {
+ if(currentButton == NULL) return;
+
+ lv_obj_t * parent = lv_obj_get_parent(currentButton);
+ const uint32_t pos = lv_obj_get_child_cnt(parent) / 2;
+
+ lv_obj_move_to_index(currentButton, pos);
+
+ lv_obj_scroll_to_view(currentButton, LV_ANIM_ON);
+ }
+}
+
+static void event_handler_dn(lv_event_t * e)
+{
+ const lv_event_code_t code = lv_event_get_code(e);
+ if((code == LV_EVENT_CLICKED) || (code == LV_EVENT_LONG_PRESSED_REPEAT)) {
+ if(currentButton == NULL) return;
+ const uint32_t index = lv_obj_get_index(currentButton);
+
+ lv_obj_move_to_index(currentButton, index + 1);
+ lv_obj_scroll_to_view(currentButton, LV_ANIM_ON);
+ }
+}
+
+static void event_handler_bottom(lv_event_t * e)
+{
+ const lv_event_code_t code = lv_event_get_code(e);
+ if(code == LV_EVENT_CLICKED) {
+ if(currentButton == NULL) return;
+ lv_obj_move_foreground(currentButton);
+ lv_obj_scroll_to_view(currentButton, LV_ANIM_ON);
+ }
+}
+
+static void event_handler_swap(lv_event_t * e)
+{
+ const lv_event_code_t code = lv_event_get_code(e);
+ // lv_obj_t* obj = lv_event_get_target(e);
+ if((code == LV_EVENT_CLICKED) || (code == LV_EVENT_LONG_PRESSED_REPEAT)) {
+ uint32_t cnt = lv_obj_get_child_cnt(list1);
+ for(int i = 0; i < 100; i++)
+ if(cnt > 1) {
+ lv_obj_t * obj = lv_obj_get_child(list1, rand() % cnt);
+ lv_obj_move_to_index(obj, rand() % cnt);
+ if(currentButton != NULL) {
+ lv_obj_scroll_to_view(currentButton, LV_ANIM_ON);
+ }
+ }
+ }
+}
+
+void lv_example_list_2(void)
+{
+ /*Create a list*/
+ list1 = lv_list_create(lv_scr_act());
+ lv_obj_set_size(list1, lv_pct(60), lv_pct(100));
+ lv_obj_set_style_pad_row(list1, 5, 0);
+
+ /*Add buttons to the list*/
+ lv_obj_t * btn;
+ int i;
+ for(i = 0; i < 15; i++) {
+ btn = lv_btn_create(list1);
+ lv_obj_set_width(btn, lv_pct(50));
+ lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
+
+ lv_obj_t * lab = lv_label_create(btn);
+ lv_label_set_text_fmt(lab, "Item %d", i);
+ }
+
+ /*Select the first button by default*/
+ currentButton = lv_obj_get_child(list1, 0);
+ lv_obj_add_state(currentButton, LV_STATE_CHECKED);
+
+ /*Create a second list with up and down buttons*/
+ list2 = lv_list_create(lv_scr_act());
+ lv_obj_set_size(list2, lv_pct(40), lv_pct(100));
+ lv_obj_align(list2, LV_ALIGN_TOP_RIGHT, 0, 0);
+ lv_obj_set_flex_flow(list2, LV_FLEX_FLOW_COLUMN);
+
+ btn = lv_list_add_btn(list2, NULL, "Top");
+ lv_obj_add_event_cb(btn, event_handler_top, LV_EVENT_ALL, NULL);
+ lv_group_remove_obj(btn);
+
+ btn = lv_list_add_btn(list2, LV_SYMBOL_UP, "Up");
+ lv_obj_add_event_cb(btn, event_handler_up, LV_EVENT_ALL, NULL);
+ lv_group_remove_obj(btn);
+
+ btn = lv_list_add_btn(list2, LV_SYMBOL_LEFT, "Center");
+ lv_obj_add_event_cb(btn, event_handler_center, LV_EVENT_ALL, NULL);
+ lv_group_remove_obj(btn);
+
+ btn = lv_list_add_btn(list2, LV_SYMBOL_DOWN, "Down");
+ lv_obj_add_event_cb(btn, event_handler_dn, LV_EVENT_ALL, NULL);
+ lv_group_remove_obj(btn);
+
+ btn = lv_list_add_btn(list2, NULL, "Bottom");
+ lv_obj_add_event_cb(btn, event_handler_bottom, LV_EVENT_ALL, NULL);
+ lv_group_remove_obj(btn);
+
+ btn = lv_list_add_btn(list2, LV_SYMBOL_SHUFFLE, "Shuffle");
+ lv_obj_add_event_cb(btn, event_handler_swap, LV_EVENT_ALL, NULL);
+ lv_group_remove_obj(btn);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/list/lv_example_list_2.py b/lib/lvgl/examples/widgets/list/lv_example_list_2.py
new file mode 100644
index 00000000..bf553c37
--- /dev/null
+++ b/lib/lvgl/examples/widgets/list/lv_example_list_2.py
@@ -0,0 +1,137 @@
+import urandom
+
+currentButton = None
+list1 = None
+
+def event_handler(evt):
+ global currentButton
+ code = evt.get_code()
+ obj = evt.get_target()
+ if code == lv.EVENT.CLICKED:
+ if currentButton == obj:
+ currentButton = None
+ else:
+ currentButton = obj
+ parent = obj.get_parent()
+ for i in range( parent.get_child_cnt()):
+ child = parent.get_child(i)
+ if child == currentButton:
+ child.add_state(lv.STATE.CHECKED)
+ else:
+ child.clear_state(lv.STATE.CHECKED)
+
+def event_handler_top(evt):
+ global currentButton
+ code = evt.get_code()
+ obj = evt.get_target()
+ if code == lv.EVENT.CLICKED:
+ if currentButton == None:
+ return
+ currentButton.move_background()
+ currentButton.scroll_to_view( lv.ANIM.ON)
+
+def event_handler_up(evt):
+ global currentButton
+ code = evt.get_code()
+ obj = evt.get_target()
+ if code == lv.EVENT.CLICKED or code == lv.EVENT.LONG_PRESSED_REPEAT:
+ if currentButton == None:
+ return
+ index = currentButton.get_index()
+ if index <= 0:
+ return
+ currentButton.move_to_index(index - 1)
+ currentButton.scroll_to_view(lv.ANIM.ON)
+
+def event_handler_center(evt):
+ global currentButton
+ code = evt.get_code()
+ obj = evt.get_target()
+ if code == lv.EVENT.CLICKED or code == lv.EVENT.LONG_PRESSED_REPEAT:
+ if currentButton == None:
+ return
+ parent = currentButton.get_parent()
+ pos = parent.get_child_cnt() // 2
+ currentButton.move_to_index(pos)
+ currentButton.scroll_to_view(lv.ANIM.ON)
+
+def event_handler_dn(evt):
+ global currentButton
+ code = evt.get_code()
+ obj = evt.get_target()
+ if code == lv.EVENT.CLICKED or code == lv.EVENT.LONG_PRESSED_REPEAT:
+ if currentButton == None:
+ return
+ index = currentButton.get_index()
+ currentButton.move_to_index(index + 1)
+ currentButton.scroll_to_view(lv.ANIM.ON)
+
+def event_handler_bottom(evt):
+ global currentButton
+ code = evt.get_code()
+ obj = evt.get_target()
+ if code == lv.EVENT.CLICKED or code == lv.EVENT.LONG_PRESSED_REPEAT:
+ if currentButton == None:
+ return
+ currentButton.move_foreground()
+ currentButton.scroll_to_view(lv.ANIM.ON)
+
+def event_handler_swap(evt):
+ global currentButton
+ global list1
+ code = evt.get_code()
+ obj = evt.get_target()
+ if code == lv.EVENT.CLICKED:
+ cnt = list1.get_child_cnt()
+ for i in range(100):
+ if cnt > 1:
+ obj = list1.get_child(urandom.getrandbits(32) % cnt )
+ obj.move_to_index(urandom.getrandbits(32) % cnt)
+ if currentButton != None:
+ currentButton.scroll_to_view(lv.ANIM.ON)
+
+#Create a list with buttons that can be sorted
+list1 = lv.list(lv.scr_act())
+list1.set_size(lv.pct(60), lv.pct(100))
+list1.set_style_pad_row( 5, 0)
+
+for i in range(15):
+ btn = lv.btn(list1)
+ btn.set_width(lv.pct(100))
+ btn.add_event_cb( event_handler, lv.EVENT.CLICKED, None)
+ lab = lv.label(btn)
+ lab.set_text("Item " + str(i))
+
+#Select the first button by default
+currentButton = list1.get_child(0)
+currentButton.add_state(lv.STATE.CHECKED)
+
+#Create a second list with up and down buttons
+list2 = lv.list(lv.scr_act())
+list2.set_size(lv.pct(40), lv.pct(100))
+list2.align(lv.ALIGN.TOP_RIGHT, 0, 0)
+list2.set_flex_flow(lv.FLEX_FLOW.COLUMN)
+
+btn = list2.add_btn(None, "Top")
+btn.add_event_cb(event_handler_top, lv.EVENT.ALL, None)
+lv.group_remove_obj(btn)
+
+btn = list2.add_btn(lv.SYMBOL.UP, "Up")
+btn.add_event_cb(event_handler_up, lv.EVENT.ALL, None)
+lv.group_remove_obj(btn)
+
+btn = list2.add_btn(lv.SYMBOL.LEFT, "Center")
+btn.add_event_cb(event_handler_center, lv.EVENT.ALL, None)
+lv.group_remove_obj(btn)
+
+btn = list2.add_btn(lv.SYMBOL.DOWN, "Down")
+btn.add_event_cb(event_handler_dn, lv.EVENT.ALL, None)
+lv.group_remove_obj(btn)
+
+btn = list2.add_btn(None, "Bottom")
+btn.add_event_cb(event_handler_bottom, lv.EVENT.ALL, None)
+lv.group_remove_obj(btn)
+
+btn = list2.add_btn(lv.SYMBOL.SHUFFLE, "Shuffle")
+btn.add_event_cb(event_handler_swap, lv.EVENT.ALL, None)
+lv.group_remove_obj(btn)
diff --git a/lib/lvgl/examples/widgets/list/test.py b/lib/lvgl/examples/widgets/list/test.py
new file mode 100755
index 00000000..1d2a9f11
--- /dev/null
+++ b/lib/lvgl/examples/widgets/list/test.py
@@ -0,0 +1,43 @@
+#!/opt/bin/lv_micropython -i
+import lvgl as lv
+import display_driver
+def event_handler(e):
+ code = e.get_code()
+ obj = e.get_target()
+ if code == lv.EVENT.CLICKED:
+ print("Clicked: list1." + list1.get_btn_text(obj))
+
+# Create a list
+list1 = lv.list(lv.scr_act())
+list1.set_size(180, 220)
+list1.center()
+
+# Add buttons to the list
+list1.add_text("File")
+btn_new = list1.add_btn(lv.SYMBOL.FILE, "New")
+btn_new.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_open = list1.add_btn(lv.SYMBOL.DIRECTORY, "Open")
+btn_open.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_save = list1.add_btn(lv.SYMBOL.SAVE, "Save")
+btn_save.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_delete = list1.add_btn(lv.SYMBOL.CLOSE, "Delete")
+btn_delete.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_edit = list1.add_btn(lv.SYMBOL.EDIT, "Edit")
+btn_edit.add_event_cb(event_handler,lv.EVENT.ALL, None)
+
+list1.add_text("Connectivity")
+btn_bluetooth = list1.add_btn(lv.SYMBOL.BLUETOOTH, "Bluetooth")
+btn_bluetooth.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_navig = list1.add_btn(lv.SYMBOL.GPS, "Navigation")
+btn_navig.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_USB = list1.add_btn(lv.SYMBOL.USB, "USB")
+btn_USB.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_battery = list1.add_btn(lv.SYMBOL.BATTERY_FULL, "Battery")
+btn_battery.add_event_cb(event_handler,lv.EVENT.ALL, None)
+
+list1.add_text("Exit")
+btn_apply = list1.add_btn(lv.SYMBOL.OK, "Apply")
+btn_apply.add_event_cb(event_handler,lv.EVENT.ALL, None)
+btn_close = list1.add_btn(lv.SYMBOL.CLOSE, "Close")
+btn_close.add_event_cb(event_handler,lv.EVENT.ALL, None)
+
diff --git a/lib/lvgl/examples/widgets/lv_example_widgets.h b/lib/lvgl/examples/widgets/lv_example_widgets.h
new file mode 100644
index 00000000..1d1ae16b
--- /dev/null
+++ b/lib/lvgl/examples/widgets/lv_example_widgets.h
@@ -0,0 +1,148 @@
+/**
+ * @file lv_example_widgets.h
+ *
+ */
+
+#ifndef LV_EXAMPLE_WIDGETS_H
+#define LV_EXAMPLE_WIDGETS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*********************
+ * INCLUDES
+ *********************/
+
+/*********************
+ * DEFINES
+ *********************/
+
+/**********************
+ * TYPEDEFS
+ **********************/
+
+/**********************
+ * GLOBAL PROTOTYPES
+ **********************/
+void lv_example_arc_1(void);
+void lv_example_arc_2(void);
+
+void lv_example_animimg_1(void);
+
+void lv_example_bar_1(void);
+void lv_example_bar_2(void);
+void lv_example_bar_3(void);
+void lv_example_bar_4(void);
+void lv_example_bar_5(void);
+void lv_example_bar_6(void);
+
+void lv_example_btn_1(void);
+void lv_example_btn_2(void);
+void lv_example_btn_3(void);
+
+void lv_example_btnmatrix_1(void);
+void lv_example_btnmatrix_2(void);
+void lv_example_btnmatrix_3(void);
+
+void lv_example_calendar_1(void);
+
+void lv_example_canvas_1(void);
+void lv_example_canvas_2(void);
+
+void lv_example_chart_1(void);
+void lv_example_chart_2(void);
+void lv_example_chart_3(void);
+void lv_example_chart_4(void);
+void lv_example_chart_5(void);
+void lv_example_chart_6(void);
+void lv_example_chart_7(void);
+void lv_example_chart_8(void);
+void lv_example_chart_9(void);
+
+void lv_example_checkbox_1(void);
+void lv_example_checkbox_2(void);
+
+void lv_example_colorwheel_1(void);
+
+void lv_example_dropdown_1(void);
+void lv_example_dropdown_2(void);
+void lv_example_dropdown_3(void);
+
+void lv_example_img_1(void);
+void lv_example_img_2(void);
+void lv_example_img_3(void);
+void lv_example_img_4(void);
+
+void lv_example_imgbtn_1(void);
+
+void lv_example_keyboard_1(void);
+
+void lv_example_label_1(void);
+void lv_example_label_2(void);
+void lv_example_label_3(void);
+void lv_example_label_4(void);
+void lv_example_label_5(void);
+
+void lv_example_led_1(void);
+
+void lv_example_line_1(void);
+
+void lv_example_list_1(void);
+void lv_example_list_2(void);
+
+void lv_example_menu_1(void);
+void lv_example_menu_2(void);
+void lv_example_menu_3(void);
+void lv_example_menu_4(void);
+void lv_example_menu_5(void);
+
+void lv_example_meter_1(void);
+void lv_example_meter_2(void);
+void lv_example_meter_3(void);
+void lv_example_meter_4(void);
+
+void lv_example_msgbox_1(void);
+
+void lv_example_obj_1(void);
+void lv_example_obj_2(void);
+
+void lv_example_roller_1(void);
+void lv_example_roller_2(void);
+void lv_example_roller_3(void);
+
+void lv_example_slider_1(void);
+void lv_example_slider_2(void);
+void lv_example_slider_3(void);
+
+void lv_example_spinbox_1(void);
+
+void lv_example_spinner_1(void);
+
+void lv_example_switch_1(void);
+
+void lv_example_table_1(void);
+void lv_example_table_2(void);
+
+void lv_example_tabview_1(void);
+void lv_example_tabview_2(void);
+
+void lv_example_textarea_1(void);
+void lv_example_textarea_2(void);
+void lv_example_textarea_3(void);
+
+void lv_example_tileview_1(void);
+
+void lv_example_win_1(void);
+
+void lv_example_span_1(void);
+
+/**********************
+ * MACROS
+ **********************/
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif /*LV_EX_WIDGETS_H*/
diff --git a/lib/lvgl/examples/widgets/menu/index.rst b/lib/lvgl/examples/widgets/menu/index.rst
new file mode 100644
index 00000000..4a5e7c8c
--- /dev/null
+++ b/lib/lvgl/examples/widgets/menu/index.rst
@@ -0,0 +1,31 @@
+
+Simple Menu
+""""""""""""""""
+
+.. lv_example:: widgets/menu/lv_example_menu_1
+ :language: c
+
+Simple Menu with root btn
+""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/menu/lv_example_menu_2
+ :language: c
+
+Simple Menu with custom header
+""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/menu/lv_example_menu_3
+ :language: c
+
+Simple Menu with floating btn to add new menu page
+""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/menu/lv_example_menu_4
+ :language: c
+
+Complex Menu
+""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/menu/lv_example_menu_5
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/menu/lv_example_menu_1.c b/lib/lvgl/examples/widgets/menu/lv_example_menu_1.c
new file mode 100644
index 00000000..db8d3405
--- /dev/null
+++ b/lib/lvgl/examples/widgets/menu/lv_example_menu_1.c
@@ -0,0 +1,40 @@
+#include "../../lv_examples.h"
+#if LV_USE_MENU && LV_BUILD_EXAMPLES
+
+void lv_example_menu_1(void)
+{
+ /*Create a menu object*/
+ lv_obj_t * menu = lv_menu_create(lv_scr_act());
+ lv_obj_set_size(menu, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
+ lv_obj_center(menu);
+
+ lv_obj_t * cont;
+ lv_obj_t * label;
+
+ /*Create a sub page*/
+ lv_obj_t * sub_page = lv_menu_page_create(menu, NULL);
+
+ cont = lv_menu_cont_create(sub_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Hello, I am hiding here");
+
+ /*Create a main page*/
+ lv_obj_t * main_page = lv_menu_page_create(menu, NULL);
+
+ cont = lv_menu_cont_create(main_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Item 1");
+
+ cont = lv_menu_cont_create(main_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Item 2");
+
+ cont = lv_menu_cont_create(main_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Item 3 (Click me!)");
+ lv_menu_set_load_page_event(menu, cont, sub_page);
+
+ lv_menu_set_page(menu, main_page);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/menu/lv_example_menu_1.py b/lib/lvgl/examples/widgets/menu/lv_example_menu_1.py
new file mode 100644
index 00000000..1f8c8128
--- /dev/null
+++ b/lib/lvgl/examples/widgets/menu/lv_example_menu_1.py
@@ -0,0 +1,28 @@
+# Create a menu object
+menu = lv.menu(lv.scr_act())
+menu.set_size(320, 240)
+menu.center()
+
+# Create a sub page
+sub_page = lv.menu_page(menu, None)
+cont = lv.menu_cont(sub_page)
+label = lv.label(cont)
+label.set_text("Hello, I am hiding here")
+
+# Create a main page
+main_page = lv.menu_page(menu, None)
+
+cont = lv.menu_cont(main_page)
+label = lv.label(cont)
+label.set_text("Item 1")
+
+cont = lv.menu_cont(main_page)
+label = lv.label(cont)
+label.set_text("Item 2")
+
+cont = lv.menu_cont(main_page)
+label = lv.label(cont)
+label.set_text("Item 3 (Click me!)")
+menu.set_load_page_event(cont, sub_page)
+
+menu.set_page(main_page) \ No newline at end of file
diff --git a/lib/lvgl/examples/widgets/menu/lv_example_menu_2.c b/lib/lvgl/examples/widgets/menu/lv_example_menu_2.c
new file mode 100644
index 00000000..fe11dc81
--- /dev/null
+++ b/lib/lvgl/examples/widgets/menu/lv_example_menu_2.c
@@ -0,0 +1,52 @@
+#include "../../lv_examples.h"
+#if LV_USE_MENU && LV_USE_MSGBOX && LV_BUILD_EXAMPLES
+
+static void back_event_handler(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+ lv_obj_t * menu = lv_event_get_user_data(e);
+
+ if(lv_menu_back_btn_is_root(menu, obj)) {
+ lv_obj_t * mbox1 = lv_msgbox_create(NULL, "Hello", "Root back btn click.", NULL, true);
+ lv_obj_center(mbox1);
+ }
+}
+
+void lv_example_menu_2(void)
+{
+ lv_obj_t * menu = lv_menu_create(lv_scr_act());
+ lv_menu_set_mode_root_back_btn(menu, LV_MENU_ROOT_BACK_BTN_ENABLED);
+ lv_obj_add_event_cb(menu, back_event_handler, LV_EVENT_CLICKED, menu);
+ lv_obj_set_size(menu, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
+ lv_obj_center(menu);
+
+ lv_obj_t * cont;
+ lv_obj_t * label;
+
+ /*Create a sub page*/
+ lv_obj_t * sub_page = lv_menu_page_create(menu, NULL);
+
+ cont = lv_menu_cont_create(sub_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Hello, I am hiding here");
+
+ /*Create a main page*/
+ lv_obj_t * main_page = lv_menu_page_create(menu, NULL);
+
+ cont = lv_menu_cont_create(main_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Item 1");
+
+ cont = lv_menu_cont_create(main_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Item 2");
+
+ cont = lv_menu_cont_create(main_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Item 3 (Click me!)");
+ lv_menu_set_load_page_event(menu, cont, sub_page);
+
+ lv_menu_set_page(menu, main_page);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/menu/lv_example_menu_2.py b/lib/lvgl/examples/widgets/menu/lv_example_menu_2.py
new file mode 100644
index 00000000..5787f540
--- /dev/null
+++ b/lib/lvgl/examples/widgets/menu/lv_example_menu_2.py
@@ -0,0 +1,36 @@
+def back_event_handler(e):
+ obj = e.get_target()
+ if menu.back_btn_is_root(obj):
+ mbox1 = lv.msgbox(lv.scr_act(), "Hello", "Root back btn click.", None, True)
+ mbox1.center()
+
+# Create a menu object
+menu = lv.menu(lv.scr_act())
+menu.set_mode_root_back_btn(lv.menu.ROOT_BACK_BTN.ENABLED)
+menu.add_event_cb(back_event_handler, lv.EVENT.CLICKED, None)
+menu.set_size(320, 240)
+menu.center()
+
+# Create a sub page
+sub_page = lv.menu_page(menu, None)
+cont = lv.menu_cont(sub_page)
+label = lv.label(cont)
+label.set_text("Hello, I am hiding here")
+
+# Create a main page
+main_page = lv.menu_page(menu, None)
+
+cont = lv.menu_cont(main_page)
+label = lv.label(cont)
+label.set_text("Item 1")
+
+cont = lv.menu_cont(main_page)
+label = lv.label(cont)
+label.set_text("Item 2")
+
+cont = lv.menu_cont(main_page)
+label = lv.label(cont)
+label.set_text("Item 3 (Click me!)")
+menu.set_load_page_event(cont, sub_page)
+
+menu.set_page(main_page) \ No newline at end of file
diff --git a/lib/lvgl/examples/widgets/menu/lv_example_menu_3.c b/lib/lvgl/examples/widgets/menu/lv_example_menu_3.c
new file mode 100644
index 00000000..24b9f6c5
--- /dev/null
+++ b/lib/lvgl/examples/widgets/menu/lv_example_menu_3.c
@@ -0,0 +1,59 @@
+#include "../../lv_examples.h"
+#if LV_USE_MENU && LV_USE_USER_DATA && LV_BUILD_EXAMPLES
+
+void lv_example_menu_3(void)
+{
+ /*Create a menu object*/
+ lv_obj_t * menu = lv_menu_create(lv_scr_act());
+ lv_obj_set_size(menu, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
+ lv_obj_center(menu);
+
+ /*Modify the header*/
+ lv_obj_t * back_btn = lv_menu_get_main_header_back_btn(menu);
+ lv_obj_t * back_btn_label = lv_label_create(back_btn);
+ lv_label_set_text(back_btn_label, "Back");
+
+ lv_obj_t * cont;
+ lv_obj_t * label;
+
+ /*Create sub pages*/
+ lv_obj_t * sub_1_page = lv_menu_page_create(menu, "Page 1");
+
+ cont = lv_menu_cont_create(sub_1_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Hello, I am hiding here");
+
+ lv_obj_t * sub_2_page = lv_menu_page_create(menu, "Page 2");
+
+ cont = lv_menu_cont_create(sub_2_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Hello, I am hiding here");
+
+ lv_obj_t * sub_3_page = lv_menu_page_create(menu, "Page 3");
+
+ cont = lv_menu_cont_create(sub_3_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Hello, I am hiding here");
+
+ /*Create a main page*/
+ lv_obj_t * main_page = lv_menu_page_create(menu, NULL);
+
+ cont = lv_menu_cont_create(main_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Item 1 (Click me!)");
+ lv_menu_set_load_page_event(menu, cont, sub_1_page);
+
+ cont = lv_menu_cont_create(main_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Item 2 (Click me!)");
+ lv_menu_set_load_page_event(menu, cont, sub_2_page);
+
+ cont = lv_menu_cont_create(main_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Item 3 (Click me!)");
+ lv_menu_set_load_page_event(menu, cont, sub_3_page);
+
+ lv_menu_set_page(menu, main_page);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/menu/lv_example_menu_3.py b/lib/lvgl/examples/widgets/menu/lv_example_menu_3.py
new file mode 100644
index 00000000..bbaf937b
--- /dev/null
+++ b/lib/lvgl/examples/widgets/menu/lv_example_menu_3.py
@@ -0,0 +1,43 @@
+# Create a menu object
+menu = lv.menu(lv.scr_act())
+menu.set_size(320, 240)
+menu.center()
+
+# Create sub pages
+sub_page_1 = lv.menu_page(menu, "Page 1")
+
+cont = lv.menu_cont(sub_page_1)
+label = lv.label(cont)
+label.set_text("Hello, I am hiding here")
+
+sub_page_2 = lv.menu_page(menu, "Page 2")
+
+cont = lv.menu_cont(sub_page_2)
+label = lv.label(cont)
+label.set_text("Hello, I am hiding here")
+
+sub_page_3 = lv.menu_page(menu, "Page 3")
+
+cont = lv.menu_cont(sub_page_3)
+label = lv.label(cont)
+label.set_text("Hello, I am hiding here")
+
+# Create a main page
+main_page = lv.menu_page(menu, None)
+
+cont = lv.menu_cont(main_page)
+label = lv.label(cont)
+label.set_text("Item 1 (Click me!)")
+menu.set_load_page_event(cont, sub_page_1)
+
+cont = lv.menu_cont(main_page)
+label = lv.label(cont)
+label.set_text("Item 2 (Click me!)")
+menu.set_load_page_event(cont, sub_page_2)
+
+cont = lv.menu_cont(main_page)
+label = lv.label(cont)
+label.set_text("Item 3 (Click me!)")
+menu.set_load_page_event(cont, sub_page_3)
+
+menu.set_page(main_page) \ No newline at end of file
diff --git a/lib/lvgl/examples/widgets/menu/lv_example_menu_4.c b/lib/lvgl/examples/widgets/menu/lv_example_menu_4.c
new file mode 100644
index 00000000..5807e5d9
--- /dev/null
+++ b/lib/lvgl/examples/widgets/menu/lv_example_menu_4.c
@@ -0,0 +1,70 @@
+#include "../../lv_examples.h"
+#if LV_USE_MENU && LV_BUILD_EXAMPLES
+
+static uint32_t btn_cnt = 1;
+static lv_obj_t * main_page;
+static lv_obj_t * menu;
+
+static void float_btn_event_cb(lv_event_t * e)
+{
+ LV_UNUSED(e);
+
+ btn_cnt++;
+
+ lv_obj_t * cont;
+ lv_obj_t * label;
+
+ lv_obj_t * sub_page = lv_menu_page_create(menu, NULL);
+
+ cont = lv_menu_cont_create(sub_page);
+ label = lv_label_create(cont);
+ lv_label_set_text_fmt(label, "Hello, I am hiding inside %i", btn_cnt);
+
+ cont = lv_menu_cont_create(main_page);
+ label = lv_label_create(cont);
+ lv_label_set_text_fmt(label, "Item %i", btn_cnt);
+ lv_menu_set_load_page_event(menu, cont, sub_page);
+
+ lv_obj_scroll_to_view_recursive(cont, LV_ANIM_ON);
+}
+
+void lv_example_menu_4(void)
+{
+ /*Create a menu object*/
+ menu = lv_menu_create(lv_scr_act());
+ lv_obj_set_size(menu, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
+ lv_obj_center(menu);
+
+ lv_obj_t * cont;
+ lv_obj_t * label;
+
+ /*Create a sub page*/
+ lv_obj_t * sub_page = lv_menu_page_create(menu, NULL);
+
+ cont = lv_menu_cont_create(sub_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Hello, I am hiding inside the first item");
+
+ /*Create a main page*/
+ main_page = lv_menu_page_create(menu, NULL);
+
+ cont = lv_menu_cont_create(main_page);
+ label = lv_label_create(cont);
+ lv_label_set_text(label, "Item 1");
+ lv_menu_set_load_page_event(menu, cont, sub_page);
+
+ lv_menu_set_page(menu, main_page);
+
+ /*Create floating btn*/
+ lv_obj_t * float_btn = lv_btn_create(lv_scr_act());
+ lv_obj_set_size(float_btn, 50, 50);
+ lv_obj_add_flag(float_btn, LV_OBJ_FLAG_FLOATING);
+ lv_obj_align(float_btn, LV_ALIGN_BOTTOM_RIGHT, -10, -10);
+ lv_obj_add_event_cb(float_btn, float_btn_event_cb, LV_EVENT_CLICKED, menu);
+ lv_obj_set_style_radius(float_btn, LV_RADIUS_CIRCLE, 0);
+ lv_obj_set_style_bg_img_src(float_btn, LV_SYMBOL_PLUS, 0);
+ lv_obj_set_style_text_font(float_btn, lv_theme_get_font_large(float_btn), 0);
+}
+
+#endif
+
diff --git a/lib/lvgl/examples/widgets/menu/lv_example_menu_4.py b/lib/lvgl/examples/widgets/menu/lv_example_menu_4.py
new file mode 100644
index 00000000..4bb190d0
--- /dev/null
+++ b/lib/lvgl/examples/widgets/menu/lv_example_menu_4.py
@@ -0,0 +1,47 @@
+btn_cnt = 1
+
+def float_btn_event_cb(e):
+ global btn_cnt
+ btn_cnt += 1
+
+ sub_page = lv.menu_page(menu, None)
+
+ cont = lv.menu_cont(sub_page)
+ label = lv.label(cont)
+ label.set_text("Hello, I am hiding inside {:d}".format(btn_cnt))
+
+ cont = lv.menu_cont(main_page)
+ label = lv.label(cont)
+ label.set_text("Item {:d}".format(btn_cnt))
+ menu.set_load_page_event(cont, sub_page)
+
+# Create a menu object
+menu = lv.menu(lv.scr_act())
+menu.set_size(320, 240)
+menu.center()
+
+# Create a sub page
+sub_page = lv.menu_page(menu, None)
+
+cont = lv.menu_cont(sub_page)
+label = lv.label(cont)
+label.set_text("Hello, I am hiding inside the first item")
+
+# Create a main page
+main_page = lv.menu_page(menu, None)
+
+cont = lv.menu_cont(main_page)
+label = lv.label(cont)
+label.set_text("Item 1")
+menu.set_load_page_event(cont, sub_page)
+
+menu.set_page(main_page)
+
+float_btn = lv.btn(lv.scr_act())
+float_btn.set_size(50, 50)
+float_btn.add_flag(lv.obj.FLAG.FLOATING)
+float_btn.align(lv.ALIGN.BOTTOM_RIGHT, -10, -10)
+float_btn.add_event_cb(float_btn_event_cb, lv.EVENT.CLICKED, None)
+float_btn.set_style_radius(lv.RADIUS.CIRCLE, 0)
+float_btn.set_style_bg_img_src(lv.SYMBOL.PLUS, 0)
+float_btn.set_style_text_font(lv.theme_get_font_large(float_btn), 0) \ No newline at end of file
diff --git a/lib/lvgl/examples/widgets/menu/lv_example_menu_5.c b/lib/lvgl/examples/widgets/menu/lv_example_menu_5.c
new file mode 100644
index 00000000..e8068acf
--- /dev/null
+++ b/lib/lvgl/examples/widgets/menu/lv_example_menu_5.c
@@ -0,0 +1,199 @@
+#include "../../lv_examples.h"
+#if LV_USE_MENU && LV_USE_MSGBOX && LV_BUILD_EXAMPLES
+
+enum {
+ LV_MENU_ITEM_BUILDER_VARIANT_1,
+ LV_MENU_ITEM_BUILDER_VARIANT_2
+};
+typedef uint8_t lv_menu_builder_variant_t;
+
+static void back_event_handler(lv_event_t * e);
+static void switch_handler(lv_event_t * e);
+lv_obj_t * root_page;
+static lv_obj_t * create_text(lv_obj_t * parent, const char * icon, const char * txt,
+ lv_menu_builder_variant_t builder_variant);
+static lv_obj_t * create_slider(lv_obj_t * parent,
+ const char * icon, const char * txt, int32_t min, int32_t max, int32_t val);
+static lv_obj_t * create_switch(lv_obj_t * parent,
+ const char * icon, const char * txt, bool chk);
+
+void lv_example_menu_5(void)
+{
+ lv_obj_t * menu = lv_menu_create(lv_scr_act());
+
+ lv_color_t bg_color = lv_obj_get_style_bg_color(menu, 0);
+ if(lv_color_brightness(bg_color) > 127) {
+ lv_obj_set_style_bg_color(menu, lv_color_darken(lv_obj_get_style_bg_color(menu, 0), 10), 0);
+ }
+ else {
+ lv_obj_set_style_bg_color(menu, lv_color_darken(lv_obj_get_style_bg_color(menu, 0), 50), 0);
+ }
+ lv_menu_set_mode_root_back_btn(menu, LV_MENU_ROOT_BACK_BTN_ENABLED);
+ lv_obj_add_event_cb(menu, back_event_handler, LV_EVENT_CLICKED, menu);
+ lv_obj_set_size(menu, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
+ lv_obj_center(menu);
+
+ lv_obj_t * cont;
+ lv_obj_t * section;
+
+ /*Create sub pages*/
+ lv_obj_t * sub_mechanics_page = lv_menu_page_create(menu, NULL);
+ lv_obj_set_style_pad_hor(sub_mechanics_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0);
+ lv_menu_separator_create(sub_mechanics_page);
+ section = lv_menu_section_create(sub_mechanics_page);
+ create_slider(section, LV_SYMBOL_SETTINGS, "Velocity", 0, 150, 120);
+ create_slider(section, LV_SYMBOL_SETTINGS, "Acceleration", 0, 150, 50);
+ create_slider(section, LV_SYMBOL_SETTINGS, "Weight limit", 0, 150, 80);
+
+ lv_obj_t * sub_sound_page = lv_menu_page_create(menu, NULL);
+ lv_obj_set_style_pad_hor(sub_sound_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0);
+ lv_menu_separator_create(sub_sound_page);
+ section = lv_menu_section_create(sub_sound_page);
+ create_switch(section, LV_SYMBOL_AUDIO, "Sound", false);
+
+ lv_obj_t * sub_display_page = lv_menu_page_create(menu, NULL);
+ lv_obj_set_style_pad_hor(sub_display_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0);
+ lv_menu_separator_create(sub_display_page);
+ section = lv_menu_section_create(sub_display_page);
+ create_slider(section, LV_SYMBOL_SETTINGS, "Brightness", 0, 150, 100);
+
+ lv_obj_t * sub_software_info_page = lv_menu_page_create(menu, NULL);
+ lv_obj_set_style_pad_hor(sub_software_info_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0);
+ section = lv_menu_section_create(sub_software_info_page);
+ create_text(section, NULL, "Version 1.0", LV_MENU_ITEM_BUILDER_VARIANT_1);
+
+ lv_obj_t * sub_legal_info_page = lv_menu_page_create(menu, NULL);
+ lv_obj_set_style_pad_hor(sub_legal_info_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0);
+ section = lv_menu_section_create(sub_legal_info_page);
+ for(uint32_t i = 0; i < 15; i++) {
+ create_text(section, NULL,
+ "This is a long long long long long long long long long text, if it is long enough it may scroll.",
+ LV_MENU_ITEM_BUILDER_VARIANT_1);
+ }
+
+ lv_obj_t * sub_about_page = lv_menu_page_create(menu, NULL);
+ lv_obj_set_style_pad_hor(sub_about_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0);
+ lv_menu_separator_create(sub_about_page);
+ section = lv_menu_section_create(sub_about_page);
+ cont = create_text(section, NULL, "Software information", LV_MENU_ITEM_BUILDER_VARIANT_1);
+ lv_menu_set_load_page_event(menu, cont, sub_software_info_page);
+ cont = create_text(section, NULL, "Legal information", LV_MENU_ITEM_BUILDER_VARIANT_1);
+ lv_menu_set_load_page_event(menu, cont, sub_legal_info_page);
+
+ lv_obj_t * sub_menu_mode_page = lv_menu_page_create(menu, NULL);
+ lv_obj_set_style_pad_hor(sub_menu_mode_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0);
+ lv_menu_separator_create(sub_menu_mode_page);
+ section = lv_menu_section_create(sub_menu_mode_page);
+ cont = create_switch(section, LV_SYMBOL_AUDIO, "Sidebar enable", true);
+ lv_obj_add_event_cb(lv_obj_get_child(cont, 2), switch_handler, LV_EVENT_VALUE_CHANGED, menu);
+
+ /*Create a root page*/
+ root_page = lv_menu_page_create(menu, "Settings");
+ lv_obj_set_style_pad_hor(root_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0);
+ section = lv_menu_section_create(root_page);
+ cont = create_text(section, LV_SYMBOL_SETTINGS, "Mechanics", LV_MENU_ITEM_BUILDER_VARIANT_1);
+ lv_menu_set_load_page_event(menu, cont, sub_mechanics_page);
+ cont = create_text(section, LV_SYMBOL_AUDIO, "Sound", LV_MENU_ITEM_BUILDER_VARIANT_1);
+ lv_menu_set_load_page_event(menu, cont, sub_sound_page);
+ cont = create_text(section, LV_SYMBOL_SETTINGS, "Display", LV_MENU_ITEM_BUILDER_VARIANT_1);
+ lv_menu_set_load_page_event(menu, cont, sub_display_page);
+
+ create_text(root_page, NULL, "Others", LV_MENU_ITEM_BUILDER_VARIANT_1);
+ section = lv_menu_section_create(root_page);
+ cont = create_text(section, NULL, "About", LV_MENU_ITEM_BUILDER_VARIANT_1);
+ lv_menu_set_load_page_event(menu, cont, sub_about_page);
+ cont = create_text(section, LV_SYMBOL_SETTINGS, "Menu mode", LV_MENU_ITEM_BUILDER_VARIANT_1);
+ lv_menu_set_load_page_event(menu, cont, sub_menu_mode_page);
+
+ lv_menu_set_sidebar_page(menu, root_page);
+
+ lv_event_send(lv_obj_get_child(lv_obj_get_child(lv_menu_get_cur_sidebar_page(menu), 0), 0), LV_EVENT_CLICKED, NULL);
+}
+
+static void back_event_handler(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+ lv_obj_t * menu = lv_event_get_user_data(e);
+
+ if(lv_menu_back_btn_is_root(menu, obj)) {
+ lv_obj_t * mbox1 = lv_msgbox_create(NULL, "Hello", "Root back btn click.", NULL, true);
+ lv_obj_center(mbox1);
+ }
+}
+
+static void switch_handler(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * menu = lv_event_get_user_data(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+ if(code == LV_EVENT_VALUE_CHANGED) {
+ if(lv_obj_has_state(obj, LV_STATE_CHECKED)) {
+ lv_menu_set_page(menu, NULL);
+ lv_menu_set_sidebar_page(menu, root_page);
+ lv_event_send(lv_obj_get_child(lv_obj_get_child(lv_menu_get_cur_sidebar_page(menu), 0), 0), LV_EVENT_CLICKED, NULL);
+ }
+ else {
+ lv_menu_set_sidebar_page(menu, NULL);
+ lv_menu_clear_history(menu); /* Clear history because we will be showing the root page later */
+ lv_menu_set_page(menu, root_page);
+ }
+ }
+}
+
+static lv_obj_t * create_text(lv_obj_t * parent, const char * icon, const char * txt,
+ lv_menu_builder_variant_t builder_variant)
+{
+ lv_obj_t * obj = lv_menu_cont_create(parent);
+
+ lv_obj_t * img = NULL;
+ lv_obj_t * label = NULL;
+
+ if(icon) {
+ img = lv_img_create(obj);
+ lv_img_set_src(img, icon);
+ }
+
+ if(txt) {
+ label = lv_label_create(obj);
+ lv_label_set_text(label, txt);
+ lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR);
+ lv_obj_set_flex_grow(label, 1);
+ }
+
+ if(builder_variant == LV_MENU_ITEM_BUILDER_VARIANT_2 && icon && txt) {
+ lv_obj_add_flag(img, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
+ lv_obj_swap(img, label);
+ }
+
+ return obj;
+}
+
+static lv_obj_t * create_slider(lv_obj_t * parent, const char * icon, const char * txt, int32_t min, int32_t max,
+ int32_t val)
+{
+ lv_obj_t * obj = create_text(parent, icon, txt, LV_MENU_ITEM_BUILDER_VARIANT_2);
+
+ lv_obj_t * slider = lv_slider_create(obj);
+ lv_obj_set_flex_grow(slider, 1);
+ lv_slider_set_range(slider, min, max);
+ lv_slider_set_value(slider, val, LV_ANIM_OFF);
+
+ if(icon == NULL) {
+ lv_obj_add_flag(slider, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
+ }
+
+ return obj;
+}
+
+static lv_obj_t * create_switch(lv_obj_t * parent, const char * icon, const char * txt, bool chk)
+{
+ lv_obj_t * obj = create_text(parent, icon, txt, LV_MENU_ITEM_BUILDER_VARIANT_1);
+
+ lv_obj_t * sw = lv_switch_create(obj);
+ lv_obj_add_state(sw, chk ? LV_STATE_CHECKED : 0);
+
+ return obj;
+}
+
+#endif
+
diff --git a/lib/lvgl/examples/widgets/meter/index.rst b/lib/lvgl/examples/widgets/meter/index.rst
new file mode 100644
index 00000000..08dfb0fc
--- /dev/null
+++ b/lib/lvgl/examples/widgets/meter/index.rst
@@ -0,0 +1,28 @@
+
+Simple meter
+"""""""""""""""""""""""
+
+.. lv_example:: widgets/meter/lv_example_meter_1
+ :language: c
+
+
+A meter with multiple arcs
+"""""""""""""""""""""""""""
+
+.. lv_example:: widgets/meter/lv_example_meter_2
+ :language: c
+
+
+A clock from a meter
+"""""""""""""""""""""""
+
+.. lv_example:: widgets/meter/lv_example_meter_3
+ :language: c
+
+
+Pie chart
+"""""""""""""""""""""""
+
+.. lv_example:: widgets/meter/lv_example_meter_4
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/meter/lv_example_meter_1.c b/lib/lvgl/examples/widgets/meter/lv_example_meter_1.c
new file mode 100644
index 00000000..40686ca2
--- /dev/null
+++ b/lib/lvgl/examples/widgets/meter/lv_example_meter_1.c
@@ -0,0 +1,66 @@
+#include "../../lv_examples.h"
+#if LV_USE_METER && LV_BUILD_EXAMPLES
+
+static lv_obj_t * meter;
+
+static void set_value(void * indic, int32_t v)
+{
+ lv_meter_set_indicator_value(meter, indic, v);
+}
+
+/**
+ * A simple meter
+ */
+void lv_example_meter_1(void)
+{
+ meter = lv_meter_create(lv_scr_act());
+ lv_obj_center(meter);
+ lv_obj_set_size(meter, 200, 200);
+
+ /*Add a scale first*/
+ lv_meter_scale_t * scale = lv_meter_add_scale(meter);
+ lv_meter_set_scale_ticks(meter, scale, 41, 2, 10, lv_palette_main(LV_PALETTE_GREY));
+ lv_meter_set_scale_major_ticks(meter, scale, 8, 4, 15, lv_color_black(), 10);
+
+ lv_meter_indicator_t * indic;
+
+ /*Add a blue arc to the start*/
+ indic = lv_meter_add_arc(meter, scale, 3, lv_palette_main(LV_PALETTE_BLUE), 0);
+ lv_meter_set_indicator_start_value(meter, indic, 0);
+ lv_meter_set_indicator_end_value(meter, indic, 20);
+
+ /*Make the tick lines blue at the start of the scale*/
+ indic = lv_meter_add_scale_lines(meter, scale, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_BLUE),
+ false, 0);
+ lv_meter_set_indicator_start_value(meter, indic, 0);
+ lv_meter_set_indicator_end_value(meter, indic, 20);
+
+ /*Add a red arc to the end*/
+ indic = lv_meter_add_arc(meter, scale, 3, lv_palette_main(LV_PALETTE_RED), 0);
+ lv_meter_set_indicator_start_value(meter, indic, 80);
+ lv_meter_set_indicator_end_value(meter, indic, 100);
+
+ /*Make the tick lines red at the end of the scale*/
+ indic = lv_meter_add_scale_lines(meter, scale, lv_palette_main(LV_PALETTE_RED), lv_palette_main(LV_PALETTE_RED), false,
+ 0);
+ lv_meter_set_indicator_start_value(meter, indic, 80);
+ lv_meter_set_indicator_end_value(meter, indic, 100);
+
+ /*Add a needle line indicator*/
+ indic = lv_meter_add_needle_line(meter, scale, 4, lv_palette_main(LV_PALETTE_GREY), -10);
+
+ /*Create an animation to set the value*/
+ lv_anim_t a;
+ lv_anim_init(&a);
+ lv_anim_set_exec_cb(&a, set_value);
+ lv_anim_set_var(&a, indic);
+ lv_anim_set_values(&a, 0, 100);
+ lv_anim_set_time(&a, 2000);
+ lv_anim_set_repeat_delay(&a, 100);
+ lv_anim_set_playback_time(&a, 500);
+ lv_anim_set_playback_delay(&a, 100);
+ lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
+ lv_anim_start(&a);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/meter/lv_example_meter_1.py b/lib/lvgl/examples/widgets/meter/lv_example_meter_1.py
new file mode 100644
index 00000000..6208e6a6
--- /dev/null
+++ b/lib/lvgl/examples/widgets/meter/lv_example_meter_1.py
@@ -0,0 +1,58 @@
+#!//opt/bin/lv_micropython -i
+import utime as time
+import lvgl as lv
+import display_driver
+
+def set_value(indic, v):
+ meter.set_indicator_value(indic, v)
+
+#
+# A simple meter
+#
+meter = lv.meter(lv.scr_act())
+meter.center()
+meter.set_size(200, 200)
+
+# Add a scale first
+scale = meter.add_scale()
+meter.set_scale_ticks(scale, 51, 2, 10, lv.palette_main(lv.PALETTE.GREY))
+meter.set_scale_major_ticks(scale, 10, 4, 15, lv.color_black(), 10)
+
+indic = lv.meter_indicator_t()
+
+# Add a blue arc to the start
+indic = meter.add_arc(scale, 3, lv.palette_main(lv.PALETTE.BLUE), 0)
+meter.set_indicator_start_value(indic, 0)
+meter.set_indicator_end_value(indic, 20)
+
+# Make the tick lines blue at the start of the scale
+indic = meter.add_scale_lines(scale, lv.palette_main(lv.PALETTE.BLUE), lv.palette_main(lv.PALETTE.BLUE), False, 0)
+meter.set_indicator_start_value(indic, 0)
+meter.set_indicator_end_value(indic, 20)
+
+# Add a red arc to the end
+indic = meter.add_arc(scale, 3, lv.palette_main(lv.PALETTE.RED), 0)
+meter.set_indicator_start_value(indic, 80)
+meter.set_indicator_end_value(indic, 100)
+
+# Make the tick lines red at the end of the scale
+indic = meter.add_scale_lines(scale, lv.palette_main(lv.PALETTE.RED), lv.palette_main(lv.PALETTE.RED), False, 0)
+meter.set_indicator_start_value(indic, 80)
+meter.set_indicator_end_value(indic, 100)
+
+# Add a needle line indicator
+indic = meter.add_needle_line(scale, 4, lv.palette_main(lv.PALETTE.GREY), -10)
+
+# Create an animation to set the value
+a = lv.anim_t()
+a.init()
+a.set_var(indic)
+a.set_values(0, 100)
+a.set_time(2000)
+a.set_repeat_delay(100)
+a.set_playback_time(500)
+a.set_playback_delay(100)
+a.set_repeat_count(lv.ANIM_REPEAT.INFINITE)
+a.set_custom_exec_cb(lambda a,val: set_value(indic,val))
+lv.anim_t.start(a)
+
diff --git a/lib/lvgl/examples/widgets/meter/lv_example_meter_2.c b/lib/lvgl/examples/widgets/meter/lv_example_meter_2.c
new file mode 100644
index 00000000..811e056f
--- /dev/null
+++ b/lib/lvgl/examples/widgets/meter/lv_example_meter_2.c
@@ -0,0 +1,60 @@
+#include "../../lv_examples.h"
+#if LV_USE_METER && LV_BUILD_EXAMPLES
+
+static lv_obj_t * meter;
+
+static void set_value(void * indic, int32_t v)
+{
+ lv_meter_set_indicator_end_value(meter, indic, v);
+}
+
+
+/**
+ * A meter with multiple arcs
+ */
+void lv_example_meter_2(void)
+{
+ meter = lv_meter_create(lv_scr_act());
+ lv_obj_center(meter);
+ lv_obj_set_size(meter, 200, 200);
+
+ /*Remove the circle from the middle*/
+ lv_obj_remove_style(meter, NULL, LV_PART_INDICATOR);
+
+ /*Add a scale first*/
+ lv_meter_scale_t * scale = lv_meter_add_scale(meter);
+ lv_meter_set_scale_ticks(meter, scale, 11, 2, 10, lv_palette_main(LV_PALETTE_GREY));
+ lv_meter_set_scale_major_ticks(meter, scale, 1, 2, 30, lv_color_hex3(0xeee), 15);
+ lv_meter_set_scale_range(meter, scale, 0, 100, 270, 90);
+
+ /*Add a three arc indicator*/
+ lv_meter_indicator_t * indic1 = lv_meter_add_arc(meter, scale, 10, lv_palette_main(LV_PALETTE_RED), 0);
+ lv_meter_indicator_t * indic2 = lv_meter_add_arc(meter, scale, 10, lv_palette_main(LV_PALETTE_GREEN), -10);
+ lv_meter_indicator_t * indic3 = lv_meter_add_arc(meter, scale, 10, lv_palette_main(LV_PALETTE_BLUE), -20);
+
+ /*Create an animation to set the value*/
+ lv_anim_t a;
+ lv_anim_init(&a);
+ lv_anim_set_exec_cb(&a, set_value);
+ lv_anim_set_values(&a, 0, 100);
+ lv_anim_set_repeat_delay(&a, 100);
+ lv_anim_set_playback_delay(&a, 100);
+ lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
+
+ lv_anim_set_time(&a, 2000);
+ lv_anim_set_playback_time(&a, 500);
+ lv_anim_set_var(&a, indic1);
+ lv_anim_start(&a);
+
+ lv_anim_set_time(&a, 1000);
+ lv_anim_set_playback_time(&a, 1000);
+ lv_anim_set_var(&a, indic2);
+ lv_anim_start(&a);
+
+ lv_anim_set_time(&a, 1000);
+ lv_anim_set_playback_time(&a, 2000);
+ lv_anim_set_var(&a, indic3);
+ lv_anim_start(&a);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/meter/lv_example_meter_2.py b/lib/lvgl/examples/widgets/meter/lv_example_meter_2.py
new file mode 100644
index 00000000..2acc937e
--- /dev/null
+++ b/lib/lvgl/examples/widgets/meter/lv_example_meter_2.py
@@ -0,0 +1,69 @@
+#!//opt/bin/lv_micropython -i
+import utime as time
+import lvgl as lv
+import display_driver
+
+def set_value(indic,v):
+ meter.set_indicator_end_value(indic, v)
+
+#
+# A meter with multiple arcs
+#
+
+meter = lv.meter(lv.scr_act())
+meter.center()
+meter.set_size(200, 200)
+
+# Remove the circle from the middle
+meter.remove_style(None, lv.PART.INDICATOR)
+
+# Add a scale first
+scale = meter.add_scale()
+meter.set_scale_ticks(scale, 11, 2, 10, lv.palette_main(lv.PALETTE.GREY))
+meter.set_scale_major_ticks(scale, 1, 2, 30, lv.color_hex3(0xeee), 10)
+meter.set_scale_range(scale, 0, 100, 270, 90)
+
+# Add a three arc indicator
+indic1 = meter.add_arc(scale, 10, lv.palette_main(lv.PALETTE.RED), 0)
+indic2 = meter.add_arc(scale, 10, lv.palette_main(lv.PALETTE.GREEN), -10)
+indic3 = meter.add_arc(scale, 10, lv.palette_main(lv.PALETTE.BLUE), -20)
+
+# Create an animation to set the value
+a1 = lv.anim_t()
+a1.init()
+a1.set_values(0, 100)
+a1.set_time(2000)
+a1.set_repeat_delay(100)
+a1.set_playback_delay(100)
+a1.set_playback_time(500)
+a1.set_var(indic1)
+a1.set_repeat_count(lv.ANIM_REPEAT.INFINITE)
+a1.set_custom_exec_cb(lambda a,val: set_value(indic1,val))
+lv.anim_t.start(a1)
+
+a2 = lv.anim_t()
+a2.init()
+a2.set_values(0, 100)
+a2.set_time(1000)
+a2.set_repeat_delay(100)
+a2.set_playback_delay(100)
+a2.set_playback_time(1000)
+a2.set_var(indic2)
+a2.set_repeat_count(lv.ANIM_REPEAT.INFINITE)
+a2.set_custom_exec_cb(lambda a,val: set_value(indic2,val))
+lv.anim_t.start(a2)
+
+a3 = lv.anim_t()
+a3.init()
+a3.set_values(0, 100)
+a3.set_time(1000)
+a3.set_repeat_delay(100)
+a3.set_playback_delay(100)
+a3.set_playback_time(2000)
+a3.set_var(indic3)
+a3.set_repeat_count(lv.ANIM_REPEAT.INFINITE)
+a3.set_custom_exec_cb(lambda a,val: set_value(indic3,val))
+lv.anim_t.start(a3)
+
+
+
diff --git a/lib/lvgl/examples/widgets/meter/lv_example_meter_3.c b/lib/lvgl/examples/widgets/meter/lv_example_meter_3.c
new file mode 100644
index 00000000..6b51f851
--- /dev/null
+++ b/lib/lvgl/examples/widgets/meter/lv_example_meter_3.c
@@ -0,0 +1,54 @@
+#include "../../lv_examples.h"
+#if LV_USE_METER && LV_BUILD_EXAMPLES
+
+static lv_obj_t * meter;
+
+static void set_value(void * indic, int32_t v)
+{
+ lv_meter_set_indicator_end_value(meter, indic, v);
+}
+
+/**
+ * A clock from a meter
+ */
+void lv_example_meter_3(void)
+{
+ meter = lv_meter_create(lv_scr_act());
+ lv_obj_set_size(meter, 220, 220);
+ lv_obj_center(meter);
+
+ /*Create a scale for the minutes*/
+ /*61 ticks in a 360 degrees range (the last and the first line overlaps)*/
+ lv_meter_scale_t * scale_min = lv_meter_add_scale(meter);
+ lv_meter_set_scale_ticks(meter, scale_min, 61, 1, 10, lv_palette_main(LV_PALETTE_GREY));
+ lv_meter_set_scale_range(meter, scale_min, 0, 60, 360, 270);
+
+ /*Create another scale for the hours. It's only visual and contains only major ticks*/
+ lv_meter_scale_t * scale_hour = lv_meter_add_scale(meter);
+ lv_meter_set_scale_ticks(meter, scale_hour, 12, 0, 0, lv_palette_main(LV_PALETTE_GREY)); /*12 ticks*/
+ lv_meter_set_scale_major_ticks(meter, scale_hour, 1, 2, 20, lv_color_black(), 10); /*Every tick is major*/
+ lv_meter_set_scale_range(meter, scale_hour, 1, 12, 330, 300); /*[1..12] values in an almost full circle*/
+
+ LV_IMG_DECLARE(img_hand)
+
+ /*Add a the hands from images*/
+ lv_meter_indicator_t * indic_min = lv_meter_add_needle_img(meter, scale_min, &img_hand, 5, 5);
+ lv_meter_indicator_t * indic_hour = lv_meter_add_needle_img(meter, scale_min, &img_hand, 5, 5);
+
+ /*Create an animation to set the value*/
+ lv_anim_t a;
+ lv_anim_init(&a);
+ lv_anim_set_exec_cb(&a, set_value);
+ lv_anim_set_values(&a, 0, 60);
+ lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
+ lv_anim_set_time(&a, 2000); /*2 sec for 1 turn of the minute hand (1 hour)*/
+ lv_anim_set_var(&a, indic_min);
+ lv_anim_start(&a);
+
+ lv_anim_set_var(&a, indic_hour);
+ lv_anim_set_time(&a, 24000); /*24 sec for 1 turn of the hour hand*/
+ lv_anim_set_values(&a, 0, 60);
+ lv_anim_start(&a);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/meter/lv_example_meter_3.py b/lib/lvgl/examples/widgets/meter/lv_example_meter_3.py
new file mode 100644
index 00000000..2d7c6daf
--- /dev/null
+++ b/lib/lvgl/examples/widgets/meter/lv_example_meter_3.py
@@ -0,0 +1,83 @@
+#!//opt/bin/lv_micropython -i
+import utime as time
+import lvgl as lv
+import display_driver
+from imagetools import get_png_info, open_png
+
+# Register PNG image decoder
+decoder = lv.img.decoder_create()
+decoder.info_cb = get_png_info
+decoder.open_cb = open_png
+
+# Create an image from the png file
+try:
+ with open('../../assets/img_hand_min.png','rb') as f:
+ img_hand_min_data = f.read()
+except:
+ print("Could not find img_hand_min.png")
+ sys.exit()
+
+img_hand_min_dsc = lv.img_dsc_t({
+ 'data_size': len(img_hand_min_data),
+ 'data': img_hand_min_data
+})
+
+# Create an image from the png file
+try:
+ with open('../../assets/img_hand_hour.png','rb') as f:
+ img_hand_hour_data = f.read()
+except:
+ print("Could not find img_hand_hour.png")
+ sys.exit()
+
+img_hand_hour_dsc = lv.img_dsc_t({
+ 'data_size': len(img_hand_hour_data),
+ 'data': img_hand_hour_data
+})
+
+def set_value(indic, v):
+ meter.set_indicator_value(indic, v)
+#
+# A clock from a meter
+#
+
+meter = lv.meter(lv.scr_act())
+meter.set_size(220, 220)
+meter.center()
+
+# Create a scale for the minutes
+# 61 ticks in a 360 degrees range (the last and the first line overlaps)
+scale_min = meter.add_scale()
+meter.set_scale_ticks(scale_min, 61, 1, 10, lv.palette_main(lv.PALETTE.GREY))
+meter.set_scale_range(scale_min, 0, 60, 360, 270)
+
+# Create another scale for the hours. It's only visual and contains only major ticks
+scale_hour = meter.add_scale()
+meter.set_scale_ticks(scale_hour, 12, 0, 0, lv.palette_main(lv.PALETTE.GREY)) # 12 ticks
+meter.set_scale_major_ticks(scale_hour, 1, 2, 20, lv.color_black(), 10) # Every tick is major
+meter.set_scale_range(scale_hour, 1, 12, 330, 300) # [1..12] values in an almost full circle
+
+# LV_IMG_DECLARE(img_hand)
+
+# Add the hands from images
+indic_min = meter.add_needle_img(scale_min, img_hand_min_dsc, 5, 5)
+indic_hour = meter.add_needle_img(scale_min, img_hand_hour_dsc, 5, 5)
+
+# Create an animation to set the value
+a1 = lv.anim_t()
+a1.init()
+a1.set_values(0, 60)
+a1.set_repeat_count(lv.ANIM_REPEAT.INFINITE)
+a1.set_time(2000) # 2 sec for 1 turn of the minute hand (1 hour)
+a1.set_var(indic_min)
+a1.set_custom_exec_cb(lambda a1,val: set_value(indic_min,val))
+lv.anim_t.start(a1)
+
+a2 = lv.anim_t()
+a2.init()
+a2.set_var(indic_hour)
+a2.set_time(24000) # 24 sec for 1 turn of the hour hand
+a2.set_values(0, 60)
+a2.set_custom_exec_cb(lambda a2,val: set_value(indic_hour,val))
+lv.anim_t.start(a2)
+
diff --git a/lib/lvgl/examples/widgets/meter/lv_example_meter_4.c b/lib/lvgl/examples/widgets/meter/lv_example_meter_4.c
new file mode 100644
index 00000000..e16fd2aa
--- /dev/null
+++ b/lib/lvgl/examples/widgets/meter/lv_example_meter_4.c
@@ -0,0 +1,38 @@
+#include "../../lv_examples.h"
+#if LV_USE_METER && LV_BUILD_EXAMPLES
+
+/**
+ * Create a pie chart
+ */
+void lv_example_meter_4(void)
+{
+ lv_obj_t * meter = lv_meter_create(lv_scr_act());
+
+ /*Remove the background and the circle from the middle*/
+ lv_obj_remove_style(meter, NULL, LV_PART_MAIN);
+ lv_obj_remove_style(meter, NULL, LV_PART_INDICATOR);
+
+ lv_obj_set_size(meter, 200, 200);
+ lv_obj_center(meter);
+
+ /*Add a scale first with no ticks.*/
+ lv_meter_scale_t * scale = lv_meter_add_scale(meter);
+ lv_meter_set_scale_ticks(meter, scale, 0, 0, 0, lv_color_black());
+ lv_meter_set_scale_range(meter, scale, 0, 100, 360, 0);
+
+ /*Add a three arc indicator*/
+ lv_coord_t indic_w = 100;
+ lv_meter_indicator_t * indic1 = lv_meter_add_arc(meter, scale, indic_w, lv_palette_main(LV_PALETTE_ORANGE), 0);
+ lv_meter_set_indicator_start_value(meter, indic1, 0);
+ lv_meter_set_indicator_end_value(meter, indic1, 40);
+
+ lv_meter_indicator_t * indic2 = lv_meter_add_arc(meter, scale, indic_w, lv_palette_main(LV_PALETTE_YELLOW), 0);
+ lv_meter_set_indicator_start_value(meter, indic2, 40); /*Start from the previous*/
+ lv_meter_set_indicator_end_value(meter, indic2, 80);
+
+ lv_meter_indicator_t * indic3 = lv_meter_add_arc(meter, scale, indic_w, lv_palette_main(LV_PALETTE_DEEP_ORANGE), 0);
+ lv_meter_set_indicator_start_value(meter, indic3, 80); /*Start from the previous*/
+ lv_meter_set_indicator_end_value(meter, indic3, 100);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/meter/lv_example_meter_4.py b/lib/lvgl/examples/widgets/meter/lv_example_meter_4.py
new file mode 100644
index 00000000..1193972a
--- /dev/null
+++ b/lib/lvgl/examples/widgets/meter/lv_example_meter_4.py
@@ -0,0 +1,32 @@
+#
+# Create a pie chart
+#
+
+meter = lv.meter(lv.scr_act())
+
+# Remove the background and the circle from the middle
+meter.remove_style(None, lv.PART.MAIN)
+meter.remove_style(None, lv.PART.INDICATOR)
+
+meter.set_size(200, 200)
+meter.center()
+
+# Add a scale first with no ticks.
+scale = meter.add_scale()
+meter.set_scale_ticks(scale, 0, 0, 0, lv.color_black())
+meter.set_scale_range(scale, 0, 100, 360, 0)
+
+# Add a three arc indicator*
+indic_w = 100
+indic1 = meter.add_arc(scale, indic_w,lv.palette_main(lv.PALETTE.ORANGE), 0)
+meter.set_indicator_start_value(indic1, 0)
+meter.set_indicator_end_value(indic1, 40)
+
+indic2 = meter.add_arc(scale, indic_w, lv.palette_main(lv.PALETTE.YELLOW), 0)
+meter.set_indicator_start_value(indic2, 40) # Start from the previous
+meter.set_indicator_end_value(indic2, 80)
+
+indic3 = meter.add_arc(scale, indic_w, lv.palette_main(lv.PALETTE.DEEP_ORANGE), 0)
+meter.set_indicator_start_value(indic3, 80) # Start from the previous
+meter.set_indicator_end_value(indic3, 100)
+
diff --git a/lib/lvgl/examples/widgets/msgbox/index.rst b/lib/lvgl/examples/widgets/msgbox/index.rst
new file mode 100644
index 00000000..04c441a3
--- /dev/null
+++ b/lib/lvgl/examples/widgets/msgbox/index.rst
@@ -0,0 +1,8 @@
+
+Simple Message box
+"""""""""""""""""""
+
+.. lv_example:: widgets/msgbox/lv_example_msgbox_1
+ :language: c
+
+
diff --git a/lib/lvgl/examples/widgets/msgbox/lv_example_msgbox_1.c b/lib/lvgl/examples/widgets/msgbox/lv_example_msgbox_1.c
new file mode 100644
index 00000000..9ae86068
--- /dev/null
+++ b/lib/lvgl/examples/widgets/msgbox/lv_example_msgbox_1.c
@@ -0,0 +1,19 @@
+#include "../../lv_examples.h"
+#if LV_USE_MSGBOX && LV_BUILD_EXAMPLES
+
+static void event_cb(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_current_target(e);
+ LV_LOG_USER("Button %s clicked", lv_msgbox_get_active_btn_text(obj));
+}
+
+void lv_example_msgbox_1(void)
+{
+ static const char * btns[] = {"Apply", "Close", ""};
+
+ lv_obj_t * mbox1 = lv_msgbox_create(NULL, "Hello", "This is a message box with two buttons.", btns, true);
+ lv_obj_add_event_cb(mbox1, event_cb, LV_EVENT_VALUE_CHANGED, NULL);
+ lv_obj_center(mbox1);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/msgbox/lv_example_msgbox_1.py b/lib/lvgl/examples/widgets/msgbox/lv_example_msgbox_1.py
new file mode 100644
index 00000000..9d3e7f78
--- /dev/null
+++ b/lib/lvgl/examples/widgets/msgbox/lv_example_msgbox_1.py
@@ -0,0 +1,10 @@
+def event_cb(e):
+ mbox = e.get_current_target()
+ print("Button %s clicked" % mbox.get_active_btn_text())
+
+btns = ["Apply", "Close", ""]
+
+mbox1 = lv.msgbox(lv.scr_act(), "Hello", "This is a message box with two buttons.", btns, True)
+mbox1.add_event_cb(event_cb, lv.EVENT.VALUE_CHANGED, None)
+mbox1.center()
+
diff --git a/lib/lvgl/examples/widgets/obj/index.rst b/lib/lvgl/examples/widgets/obj/index.rst
new file mode 100644
index 00000000..2bf39db9
--- /dev/null
+++ b/lib/lvgl/examples/widgets/obj/index.rst
@@ -0,0 +1,13 @@
+
+Base objects with custom styles
+""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/obj/lv_example_obj_1
+ :language: c
+
+Make an object draggable
+""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/obj/lv_example_obj_2
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/obj/lv_example_obj_1.c b/lib/lvgl/examples/widgets/obj/lv_example_obj_1.c
new file mode 100644
index 00000000..9c5ff7a0
--- /dev/null
+++ b/lib/lvgl/examples/widgets/obj/lv_example_obj_1.c
@@ -0,0 +1,22 @@
+#include "../../lv_examples.h"
+#if LV_BUILD_EXAMPLES
+
+void lv_example_obj_1(void)
+{
+ lv_obj_t * obj1;
+ obj1 = lv_obj_create(lv_scr_act());
+ lv_obj_set_size(obj1, 100, 50);
+ lv_obj_align(obj1, LV_ALIGN_CENTER, -60, -30);
+
+ static lv_style_t style_shadow;
+ lv_style_init(&style_shadow);
+ lv_style_set_shadow_width(&style_shadow, 10);
+ lv_style_set_shadow_spread(&style_shadow, 5);
+ lv_style_set_shadow_color(&style_shadow, lv_palette_main(LV_PALETTE_BLUE));
+
+ lv_obj_t * obj2;
+ obj2 = lv_obj_create(lv_scr_act());
+ lv_obj_add_style(obj2, &style_shadow, 0);
+ lv_obj_align(obj2, LV_ALIGN_CENTER, 60, 30);
+}
+#endif
diff --git a/lib/lvgl/examples/widgets/obj/lv_example_obj_1.py b/lib/lvgl/examples/widgets/obj/lv_example_obj_1.py
new file mode 100644
index 00000000..f627e520
--- /dev/null
+++ b/lib/lvgl/examples/widgets/obj/lv_example_obj_1.py
@@ -0,0 +1,14 @@
+obj1 = lv.obj(lv.scr_act())
+obj1.set_size(100, 50)
+obj1.align(lv.ALIGN.CENTER, -60, -30)
+
+style_shadow = lv.style_t()
+style_shadow.init()
+style_shadow.set_shadow_width(10)
+style_shadow.set_shadow_spread(5)
+style_shadow.set_shadow_color(lv.palette_main(lv.PALETTE.BLUE))
+
+obj2 = lv.obj(lv.scr_act())
+obj2.add_style(style_shadow, 0)
+obj2.align(lv.ALIGN.CENTER, 60, 30)
+
diff --git a/lib/lvgl/examples/widgets/obj/lv_example_obj_2.c b/lib/lvgl/examples/widgets/obj/lv_example_obj_2.c
new file mode 100644
index 00000000..627d509f
--- /dev/null
+++ b/lib/lvgl/examples/widgets/obj/lv_example_obj_2.c
@@ -0,0 +1,35 @@
+#include "../../lv_examples.h"
+#if LV_BUILD_EXAMPLES
+
+static void drag_event_handler(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+
+ lv_indev_t * indev = lv_indev_get_act();
+ if(indev == NULL) return;
+
+ lv_point_t vect;
+ lv_indev_get_vect(indev, &vect);
+
+ lv_coord_t x = lv_obj_get_x(obj) + vect.x;
+ lv_coord_t y = lv_obj_get_y(obj) + vect.y;
+ lv_obj_set_pos(obj, x, y);
+}
+
+
+/**
+ * Make an object dragable.
+ */
+void lv_example_obj_2(void)
+{
+ lv_obj_t * obj;
+ obj = lv_obj_create(lv_scr_act());
+ lv_obj_set_size(obj, 150, 100);
+ lv_obj_add_event_cb(obj, drag_event_handler, LV_EVENT_PRESSING, NULL);
+
+ lv_obj_t * label = lv_label_create(obj);
+ lv_label_set_text(label, "Drag me");
+ lv_obj_center(label);
+
+}
+#endif
diff --git a/lib/lvgl/examples/widgets/obj/lv_example_obj_2.py b/lib/lvgl/examples/widgets/obj/lv_example_obj_2.py
new file mode 100644
index 00000000..f1f3626d
--- /dev/null
+++ b/lib/lvgl/examples/widgets/obj/lv_example_obj_2.py
@@ -0,0 +1,25 @@
+def drag_event_handler(e):
+
+ obj = e.get_target()
+
+ indev = lv.indev_get_act()
+
+ vect = lv.point_t()
+ indev.get_vect(vect)
+ x = obj.get_x() + vect.x
+ y = obj.get_y() + vect.y
+ obj.set_pos(x, y)
+
+
+#
+# Make an object dragable.
+#
+
+obj = lv.obj(lv.scr_act())
+obj.set_size(150, 100)
+obj.add_event_cb(drag_event_handler, lv.EVENT.PRESSING, None)
+
+label = lv.label(obj)
+label.set_text("Drag me")
+label.center()
+
diff --git a/lib/lvgl/examples/widgets/roller/index.rst b/lib/lvgl/examples/widgets/roller/index.rst
new file mode 100644
index 00000000..23a81d68
--- /dev/null
+++ b/lib/lvgl/examples/widgets/roller/index.rst
@@ -0,0 +1,19 @@
+
+Simple Roller
+""""""""""""""""
+
+.. lv_example:: widgets/roller/lv_example_roller_1
+ :language: c
+
+Styling the roller
+""""""""""""""""""
+
+.. lv_example:: widgets/roller/lv_example_roller_2
+ :language: c
+
+add fade mask to roller
+"""""""""""""""""""""""
+
+.. lv_example:: widgets/roller/lv_example_roller_3
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/roller/lv_example_roller_1.c b/lib/lvgl/examples/widgets/roller/lv_example_roller_1.c
new file mode 100644
index 00000000..93dd0be1
--- /dev/null
+++ b/lib/lvgl/examples/widgets/roller/lv_example_roller_1.c
@@ -0,0 +1,41 @@
+#include "../../lv_examples.h"
+#if LV_USE_ROLLER && LV_BUILD_EXAMPLES
+
+static void event_handler(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+ if(code == LV_EVENT_VALUE_CHANGED) {
+ char buf[32];
+ lv_roller_get_selected_str(obj, buf, sizeof(buf));
+ LV_LOG_USER("Selected month: %s\n", buf);
+ }
+}
+
+/**
+ * An infinite roller with the name of the months
+ */
+void lv_example_roller_1(void)
+{
+ lv_obj_t * roller1 = lv_roller_create(lv_scr_act());
+ lv_roller_set_options(roller1,
+ "January\n"
+ "February\n"
+ "March\n"
+ "April\n"
+ "May\n"
+ "June\n"
+ "July\n"
+ "August\n"
+ "September\n"
+ "October\n"
+ "November\n"
+ "December",
+ LV_ROLLER_MODE_INFINITE);
+
+ lv_roller_set_visible_row_count(roller1, 4);
+ lv_obj_center(roller1);
+ lv_obj_add_event_cb(roller1, event_handler, LV_EVENT_ALL, NULL);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/roller/lv_example_roller_1.py b/lib/lvgl/examples/widgets/roller/lv_example_roller_1.py
new file mode 100644
index 00000000..a638321b
--- /dev/null
+++ b/lib/lvgl/examples/widgets/roller/lv_example_roller_1.py
@@ -0,0 +1,31 @@
+def event_handler(e):
+ code = e.get_code()
+ obj = e.get_target()
+ if code == lv.EVENT.VALUE_CHANGED:
+ option = " "*10
+ obj.get_selected_str(option, len(option))
+ print("Selected month: " + option.strip())
+
+#
+# An infinite roller with the name of the months
+#
+
+roller1 = lv.roller(lv.scr_act())
+roller1.set_options("\n".join([
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"]),lv.roller.MODE.INFINITE)
+
+roller1.set_visible_row_count(4)
+roller1.center()
+roller1.add_event_cb(event_handler, lv.EVENT.ALL, None)
+
diff --git a/lib/lvgl/examples/widgets/roller/lv_example_roller_2.c b/lib/lvgl/examples/widgets/roller/lv_example_roller_2.c
new file mode 100644
index 00000000..8c4b6fd2
--- /dev/null
+++ b/lib/lvgl/examples/widgets/roller/lv_example_roller_2.c
@@ -0,0 +1,60 @@
+#include "../../lv_examples.h"
+#if LV_USE_ROLLER && LV_FONT_MONTSERRAT_22 && LV_BUILD_EXAMPLES
+
+static void event_handler(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+ if(code == LV_EVENT_VALUE_CHANGED) {
+ char buf[32];
+ lv_roller_get_selected_str(obj, buf, sizeof(buf));
+ LV_LOG_USER("Selected value: %s", buf);
+ }
+}
+
+/**
+ * Roller with various alignments and larger text in the selected area
+ */
+void lv_example_roller_2(void)
+{
+ /*A style to make the selected option larger*/
+ static lv_style_t style_sel;
+ lv_style_init(&style_sel);
+ lv_style_set_text_font(&style_sel, &lv_font_montserrat_22);
+
+ const char * opts = "1\n2\n3\n4\n5\n6\n7\n8\n9\n10";
+ lv_obj_t * roller;
+
+ /*A roller on the left with left aligned text, and custom width*/
+ roller = lv_roller_create(lv_scr_act());
+ lv_roller_set_options(roller, opts, LV_ROLLER_MODE_NORMAL);
+ lv_roller_set_visible_row_count(roller, 2);
+ lv_obj_set_width(roller, 100);
+ lv_obj_add_style(roller, &style_sel, LV_PART_SELECTED);
+ lv_obj_set_style_text_align(roller, LV_TEXT_ALIGN_LEFT, 0);
+ lv_obj_align(roller, LV_ALIGN_LEFT_MID, 10, 0);
+ lv_obj_add_event_cb(roller, event_handler, LV_EVENT_ALL, NULL);
+ lv_roller_set_selected(roller, 2, LV_ANIM_OFF);
+
+ /*A roller on the middle with center aligned text, and auto (default) width*/
+ roller = lv_roller_create(lv_scr_act());
+ lv_roller_set_options(roller, opts, LV_ROLLER_MODE_NORMAL);
+ lv_roller_set_visible_row_count(roller, 3);
+ lv_obj_add_style(roller, &style_sel, LV_PART_SELECTED);
+ lv_obj_align(roller, LV_ALIGN_CENTER, 0, 0);
+ lv_obj_add_event_cb(roller, event_handler, LV_EVENT_ALL, NULL);
+ lv_roller_set_selected(roller, 5, LV_ANIM_OFF);
+
+ /*A roller on the right with right aligned text, and custom width*/
+ roller = lv_roller_create(lv_scr_act());
+ lv_roller_set_options(roller, opts, LV_ROLLER_MODE_NORMAL);
+ lv_roller_set_visible_row_count(roller, 4);
+ lv_obj_set_width(roller, 80);
+ lv_obj_add_style(roller, &style_sel, LV_PART_SELECTED);
+ lv_obj_set_style_text_align(roller, LV_TEXT_ALIGN_RIGHT, 0);
+ lv_obj_align(roller, LV_ALIGN_RIGHT_MID, -10, 0);
+ lv_obj_add_event_cb(roller, event_handler, LV_EVENT_ALL, NULL);
+ lv_roller_set_selected(roller, 8, LV_ANIM_OFF);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/roller/lv_example_roller_2.py b/lib/lvgl/examples/widgets/roller/lv_example_roller_2.py
new file mode 100644
index 00000000..7f8f7b3b
--- /dev/null
+++ b/lib/lvgl/examples/widgets/roller/lv_example_roller_2.py
@@ -0,0 +1,60 @@
+import fs_driver
+
+
+def event_handler(e):
+ code = e.get_code()
+ obj = e.get_target()
+ if code == lv.EVENT.VALUE_CHANGED:
+ option = " "*10
+ obj.get_selected_str(option, len(option))
+ print("Selected value: %s\n" + option.strip())
+
+#
+# Roller with various alignments and larger text in the selected area
+#
+
+# A style to make the selected option larger
+style_sel = lv.style_t()
+style_sel.init()
+
+try:
+ style_sel.set_text_font(lv.font_montserrat_22)
+except:
+ fs_drv = lv.fs_drv_t()
+ fs_driver.fs_register(fs_drv, 'S')
+ print("montserrat-22 not enabled in lv_conf.h, dynamically loading the font")
+ font_montserrat_22 = lv.font_load("S:" + "../../assets/font/montserrat-22.fnt")
+ style_sel.set_text_font(font_montserrat_22)
+
+opts = "\n".join(["1","2","3","4","5","6","7","8","9","10"])
+
+# A roller on the left with left aligned text, and custom width
+roller = lv.roller(lv.scr_act())
+roller.set_options(opts, lv.roller.MODE.NORMAL)
+roller.set_visible_row_count(2)
+roller.set_width(100)
+roller.add_style(style_sel, lv.PART.SELECTED)
+roller.set_style_text_align(lv.TEXT_ALIGN.LEFT, 0)
+roller.align(lv.ALIGN.LEFT_MID, 10, 0)
+roller.add_event_cb(event_handler, lv.EVENT.ALL, None)
+roller.set_selected(2, lv.ANIM.OFF)
+
+# A roller in the middle with center aligned text, and auto (default) width
+roller = lv.roller(lv.scr_act())
+roller.set_options(opts, lv.roller.MODE.NORMAL)
+roller.set_visible_row_count(3)
+roller.add_style(style_sel, lv.PART.SELECTED)
+roller.align(lv.ALIGN.CENTER, 0, 0)
+roller.add_event_cb(event_handler, lv.EVENT.ALL, None)
+roller.set_selected(5, lv.ANIM.OFF)
+
+# A roller on the right with right aligned text, and custom width
+roller = lv.roller(lv.scr_act())
+roller.set_options(opts, lv.roller.MODE.NORMAL)
+roller.set_visible_row_count(4)
+roller.set_width(80)
+roller.add_style(style_sel, lv.PART.SELECTED)
+roller.set_style_text_align(lv.TEXT_ALIGN.RIGHT, 0)
+roller.align(lv.ALIGN.RIGHT_MID, -10, 0)
+roller.add_event_cb(event_handler, lv.EVENT.ALL, None)
+roller.set_selected(8, lv.ANIM.OFF)
diff --git a/lib/lvgl/examples/widgets/roller/lv_example_roller_3.c b/lib/lvgl/examples/widgets/roller/lv_example_roller_3.c
new file mode 100644
index 00000000..c1e70ff8
--- /dev/null
+++ b/lib/lvgl/examples/widgets/roller/lv_example_roller_3.c
@@ -0,0 +1,96 @@
+#include "../../lv_examples.h"
+#if LV_USE_ROLLER && LV_DRAW_COMPLEX && LV_BUILD_EXAMPLES
+
+static void mask_event_cb(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+
+ static int16_t mask_top_id = -1;
+ static int16_t mask_bottom_id = -1;
+
+ if(code == LV_EVENT_COVER_CHECK) {
+ lv_event_set_cover_res(e, LV_COVER_RES_MASKED);
+
+ }
+ else if(code == LV_EVENT_DRAW_MAIN_BEGIN) {
+ /* add mask */
+ const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN);
+ lv_coord_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN);
+ lv_coord_t font_h = lv_font_get_line_height(font);
+
+ lv_area_t roller_coords;
+ lv_obj_get_coords(obj, &roller_coords);
+
+ lv_area_t rect_area;
+ rect_area.x1 = roller_coords.x1;
+ rect_area.x2 = roller_coords.x2;
+ rect_area.y1 = roller_coords.y1;
+ rect_area.y2 = roller_coords.y1 + (lv_obj_get_height(obj) - font_h - line_space) / 2;
+
+ lv_draw_mask_fade_param_t * fade_mask_top = lv_mem_buf_get(sizeof(lv_draw_mask_fade_param_t));
+ lv_draw_mask_fade_init(fade_mask_top, &rect_area, LV_OPA_TRANSP, rect_area.y1, LV_OPA_COVER, rect_area.y2);
+ mask_top_id = lv_draw_mask_add(fade_mask_top, NULL);
+
+ rect_area.y1 = rect_area.y2 + font_h + line_space - 1;
+ rect_area.y2 = roller_coords.y2;
+
+ lv_draw_mask_fade_param_t * fade_mask_bottom = lv_mem_buf_get(sizeof(lv_draw_mask_fade_param_t));
+ lv_draw_mask_fade_init(fade_mask_bottom, &rect_area, LV_OPA_COVER, rect_area.y1, LV_OPA_TRANSP, rect_area.y2);
+ mask_bottom_id = lv_draw_mask_add(fade_mask_bottom, NULL);
+
+ }
+ else if(code == LV_EVENT_DRAW_POST_END) {
+ lv_draw_mask_fade_param_t * fade_mask_top = lv_draw_mask_remove_id(mask_top_id);
+ lv_draw_mask_fade_param_t * fade_mask_bottom = lv_draw_mask_remove_id(mask_bottom_id);
+ lv_draw_mask_free_param(fade_mask_top);
+ lv_draw_mask_free_param(fade_mask_bottom);
+ lv_mem_buf_release(fade_mask_top);
+ lv_mem_buf_release(fade_mask_bottom);
+ mask_top_id = -1;
+ mask_bottom_id = -1;
+ }
+}
+
+/**
+ * Add a fade mask to roller.
+ */
+void lv_example_roller_3(void)
+{
+ static lv_style_t style;
+ lv_style_init(&style);
+ lv_style_set_bg_color(&style, lv_color_black());
+ lv_style_set_text_color(&style, lv_color_white());
+ lv_style_set_border_width(&style, 0);
+ lv_style_set_pad_all(&style, 0);
+ lv_obj_add_style(lv_scr_act(), &style, 0);
+
+ lv_obj_t * roller1 = lv_roller_create(lv_scr_act());
+ lv_obj_add_style(roller1, &style, 0);
+ lv_obj_set_style_bg_opa(roller1, LV_OPA_TRANSP, LV_PART_SELECTED);
+
+#if LV_FONT_MONTSERRAT_22
+ lv_obj_set_style_text_font(roller1, &lv_font_montserrat_22, LV_PART_SELECTED);
+#endif
+
+ lv_roller_set_options(roller1,
+ "January\n"
+ "February\n"
+ "March\n"
+ "April\n"
+ "May\n"
+ "June\n"
+ "July\n"
+ "August\n"
+ "September\n"
+ "October\n"
+ "November\n"
+ "December",
+ LV_ROLLER_MODE_NORMAL);
+
+ lv_obj_center(roller1);
+ lv_roller_set_visible_row_count(roller1, 3);
+ lv_obj_add_event_cb(roller1, mask_event_cb, LV_EVENT_ALL, NULL);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/roller/lv_example_roller_3.py b/lib/lvgl/examples/widgets/roller/lv_example_roller_3.py
new file mode 100644
index 00000000..13c9e9fb
--- /dev/null
+++ b/lib/lvgl/examples/widgets/roller/lv_example_roller_3.py
@@ -0,0 +1,99 @@
+import fs_driver
+import sys
+
+class Lv_Roller_3():
+
+ def __init__(self):
+ self.mask_top_id = -1
+ self.mask_bottom_id = -1
+
+ #
+ # Add a fade mask to roller.
+ #
+ style = lv.style_t()
+ style.init()
+ style.set_bg_color(lv.color_black())
+ style.set_text_color(lv.color_white())
+
+ lv.scr_act().add_style(style, 0)
+
+ roller1 = lv.roller(lv.scr_act())
+ roller1.add_style(style, 0)
+ roller1.set_style_border_width(0, 0)
+ roller1.set_style_pad_all(0, 0)
+ roller1.set_style_bg_opa(lv.OPA.TRANSP, lv.PART.SELECTED)
+
+ #if LV_FONT_MONTSERRAT_22
+ # lv_obj_set_style_text_font(roller1, &lv_font_montserrat_22, LV_PART_SELECTED);
+ #endif
+ try:
+ roller1.set_style_text_font(lv.font_montserrat_22,lv.PART.SELECTED)
+ except:
+ fs_drv = lv.fs_drv_t()
+ fs_driver.fs_register(fs_drv, 'S')
+ print("montserrat-22 not enabled in lv_conf.h, dynamically loading the font")
+ font_montserrat_22 = lv.font_load("S:" + "../../assets/font/montserrat-22.fnt")
+ roller1.set_style_text_font(font_montserrat_22,lv.PART.SELECTED)
+
+ roller1.set_options("\n".join([
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"]),lv.roller.MODE.NORMAL)
+
+ roller1.center()
+ roller1.set_visible_row_count(3)
+ roller1.add_event_cb(self.mask_event_cb, lv.EVENT.ALL, None)
+
+ def mask_event_cb(self,e):
+
+ code = e.get_code()
+ obj = e.get_target()
+
+ if code == lv.EVENT.COVER_CHECK:
+ e.set_cover_res(lv.COVER_RES.MASKED)
+
+ elif code == lv.EVENT.DRAW_MAIN_BEGIN:
+ # add mask
+ font = obj.get_style_text_font(lv.PART.MAIN)
+ line_space = obj.get_style_text_line_space(lv.PART.MAIN)
+ font_h = font.get_line_height()
+
+ roller_coords = lv.area_t()
+ obj.get_coords(roller_coords)
+
+ rect_area = lv.area_t()
+ rect_area.x1 = roller_coords.x1
+ rect_area.x2 = roller_coords.x2
+ rect_area.y1 = roller_coords.y1
+ rect_area.y2 = roller_coords.y1 + (obj.get_height() - font_h - line_space) // 2
+
+ fade_mask_top = lv.draw_mask_fade_param_t()
+ fade_mask_top.init(rect_area, lv.OPA.TRANSP, rect_area.y1, lv.OPA.COVER, rect_area.y2)
+ self.mask_top_id = lv.draw_mask_add(fade_mask_top,None)
+
+ rect_area.y1 = rect_area.y2 + font_h + line_space - 1
+ rect_area.y2 = roller_coords.y2
+
+ fade_mask_bottom = lv.draw_mask_fade_param_t()
+ fade_mask_bottom.init(rect_area, lv.OPA.COVER, rect_area.y1, lv.OPA.TRANSP, rect_area.y2)
+ self.mask_bottom_id = lv.draw_mask_add(fade_mask_bottom, None)
+
+ elif code == lv.EVENT.DRAW_POST_END:
+ fade_mask_top = lv.draw_mask_remove_id(self.mask_top_id)
+ fade_mask_bottom = lv.draw_mask_remove_id(self.mask_bottom_id)
+ # Remove the masks
+ lv.draw_mask_remove_id(self.mask_top_id)
+ lv.draw_mask_remove_id(self.mask_bottom_id)
+ self.mask_top_id = -1
+ self.mask_bottom_id = -1
+
+roller3 = Lv_Roller_3()
diff --git a/lib/lvgl/examples/widgets/slider/index.rst b/lib/lvgl/examples/widgets/slider/index.rst
new file mode 100644
index 00000000..b808de38
--- /dev/null
+++ b/lib/lvgl/examples/widgets/slider/index.rst
@@ -0,0 +1,20 @@
+
+Simple Slider
+"""""""""""""""""""""""""
+
+.. lv_example:: widgets/slider/lv_example_slider_1
+ :language: c
+
+Slider with custom style
+"""""""""""""""""""""""""
+
+.. lv_example:: widgets/slider/lv_example_slider_2
+ :language: c
+
+Slider with extended drawer
+""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/slider/lv_example_slider_3
+ :language: c
+
+
diff --git a/lib/lvgl/examples/widgets/slider/lv_example_slider_1.c b/lib/lvgl/examples/widgets/slider/lv_example_slider_1.c
new file mode 100644
index 00000000..920e1fa9
--- /dev/null
+++ b/lib/lvgl/examples/widgets/slider/lv_example_slider_1.c
@@ -0,0 +1,33 @@
+#include "../../lv_examples.h"
+#if LV_USE_SLIDER && LV_BUILD_EXAMPLES
+
+static void slider_event_cb(lv_event_t * e);
+static lv_obj_t * slider_label;
+
+/**
+ * A default slider with a label displaying the current value
+ */
+void lv_example_slider_1(void)
+{
+ /*Create a slider in the center of the display*/
+ lv_obj_t * slider = lv_slider_create(lv_scr_act());
+ lv_obj_center(slider);
+ lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
+
+ /*Create a label below the slider*/
+ slider_label = lv_label_create(lv_scr_act());
+ lv_label_set_text(slider_label, "0%");
+
+ lv_obj_align_to(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
+}
+
+static void slider_event_cb(lv_event_t * e)
+{
+ lv_obj_t * slider = lv_event_get_target(e);
+ char buf[8];
+ lv_snprintf(buf, sizeof(buf), "%d%%", (int)lv_slider_get_value(slider));
+ lv_label_set_text(slider_label, buf);
+ lv_obj_align_to(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/slider/lv_example_slider_1.py b/lib/lvgl/examples/widgets/slider/lv_example_slider_1.py
new file mode 100644
index 00000000..c3817250
--- /dev/null
+++ b/lib/lvgl/examples/widgets/slider/lv_example_slider_1.py
@@ -0,0 +1,20 @@
+#
+# A default slider with a label displaying the current value
+#
+def slider_event_cb(e):
+
+ slider = e.get_target()
+ slider_label.set_text("{:d}%".format(slider.get_value()))
+ slider_label.align_to(slider, lv.ALIGN.OUT_BOTTOM_MID, 0, 10)
+
+# Create a slider in the center of the display
+slider = lv.slider(lv.scr_act())
+slider.center()
+slider.add_event_cb(slider_event_cb, lv.EVENT.VALUE_CHANGED, None)
+
+# Create a label below the slider
+slider_label = lv.label(lv.scr_act())
+slider_label.set_text("0%")
+
+slider_label.align_to(slider, lv.ALIGN.OUT_BOTTOM_MID, 0, 10)
+
diff --git a/lib/lvgl/examples/widgets/slider/lv_example_slider_2.c b/lib/lvgl/examples/widgets/slider/lv_example_slider_2.c
new file mode 100644
index 00000000..883d61f3
--- /dev/null
+++ b/lib/lvgl/examples/widgets/slider/lv_example_slider_2.c
@@ -0,0 +1,57 @@
+#include "../../lv_examples.h"
+#if LV_USE_SLIDER && LV_BUILD_EXAMPLES
+
+
+
+/**
+ * Show how to style a slider.
+ */
+void lv_example_slider_2(void)
+{
+ /*Create a transition*/
+ static const lv_style_prop_t props[] = {LV_STYLE_BG_COLOR, 0};
+ static lv_style_transition_dsc_t transition_dsc;
+ lv_style_transition_dsc_init(&transition_dsc, props, lv_anim_path_linear, 300, 0, NULL);
+
+ static lv_style_t style_main;
+ static lv_style_t style_indicator;
+ static lv_style_t style_knob;
+ static lv_style_t style_pressed_color;
+ lv_style_init(&style_main);
+ lv_style_set_bg_opa(&style_main, LV_OPA_COVER);
+ lv_style_set_bg_color(&style_main, lv_color_hex3(0xbbb));
+ lv_style_set_radius(&style_main, LV_RADIUS_CIRCLE);
+ lv_style_set_pad_ver(&style_main, -2); /*Makes the indicator larger*/
+
+ lv_style_init(&style_indicator);
+ lv_style_set_bg_opa(&style_indicator, LV_OPA_COVER);
+ lv_style_set_bg_color(&style_indicator, lv_palette_main(LV_PALETTE_CYAN));
+ lv_style_set_radius(&style_indicator, LV_RADIUS_CIRCLE);
+ lv_style_set_transition(&style_indicator, &transition_dsc);
+
+ lv_style_init(&style_knob);
+ lv_style_set_bg_opa(&style_knob, LV_OPA_COVER);
+ lv_style_set_bg_color(&style_knob, lv_palette_main(LV_PALETTE_CYAN));
+ lv_style_set_border_color(&style_knob, lv_palette_darken(LV_PALETTE_CYAN, 3));
+ lv_style_set_border_width(&style_knob, 2);
+ lv_style_set_radius(&style_knob, LV_RADIUS_CIRCLE);
+ lv_style_set_pad_all(&style_knob, 6); /*Makes the knob larger*/
+ lv_style_set_transition(&style_knob, &transition_dsc);
+
+ lv_style_init(&style_pressed_color);
+ lv_style_set_bg_color(&style_pressed_color, lv_palette_darken(LV_PALETTE_CYAN, 2));
+
+ /*Create a slider and add the style*/
+ lv_obj_t * slider = lv_slider_create(lv_scr_act());
+ lv_obj_remove_style_all(slider); /*Remove the styles coming from the theme*/
+
+ lv_obj_add_style(slider, &style_main, LV_PART_MAIN);
+ lv_obj_add_style(slider, &style_indicator, LV_PART_INDICATOR);
+ lv_obj_add_style(slider, &style_pressed_color, LV_PART_INDICATOR | LV_STATE_PRESSED);
+ lv_obj_add_style(slider, &style_knob, LV_PART_KNOB);
+ lv_obj_add_style(slider, &style_pressed_color, LV_PART_KNOB | LV_STATE_PRESSED);
+
+ lv_obj_center(slider);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/slider/lv_example_slider_2.py b/lib/lvgl/examples/widgets/slider/lv_example_slider_2.py
new file mode 100644
index 00000000..1dd916a0
--- /dev/null
+++ b/lib/lvgl/examples/widgets/slider/lv_example_slider_2.py
@@ -0,0 +1,48 @@
+#
+# Show how to style a slider.
+#
+# Create a transition
+props = [lv.STYLE.BG_COLOR, 0]
+transition_dsc = lv.style_transition_dsc_t()
+transition_dsc.init(props, lv.anim_t.path_linear, 300, 0, None)
+
+style_main = lv.style_t()
+style_indicator = lv.style_t()
+style_knob = lv.style_t()
+style_pressed_color = lv.style_t()
+style_main.init()
+style_main.set_bg_opa(lv.OPA.COVER)
+style_main.set_bg_color(lv.color_hex3(0xbbb))
+style_main.set_radius(lv.RADIUS.CIRCLE)
+style_main.set_pad_ver(-2) # Makes the indicator larger
+
+style_indicator.init()
+style_indicator.set_bg_opa(lv.OPA.COVER)
+style_indicator.set_bg_color(lv.palette_main(lv.PALETTE.CYAN))
+style_indicator.set_radius(lv.RADIUS.CIRCLE)
+style_indicator.set_transition(transition_dsc)
+
+style_knob.init()
+style_knob.set_bg_opa(lv.OPA.COVER)
+style_knob.set_bg_color(lv.palette_main(lv.PALETTE.CYAN))
+style_knob.set_border_color(lv.palette_darken(lv.PALETTE.CYAN, 3))
+style_knob.set_border_width(2)
+style_knob.set_radius(lv.RADIUS.CIRCLE)
+style_knob.set_pad_all(6) # Makes the knob larger
+style_knob.set_transition(transition_dsc)
+
+style_pressed_color.init()
+style_pressed_color.set_bg_color(lv.palette_darken(lv.PALETTE.CYAN, 2))
+
+# Create a slider and add the style
+slider = lv.slider(lv.scr_act())
+slider.remove_style_all() # Remove the styles coming from the theme
+
+slider.add_style(style_main, lv.PART.MAIN)
+slider.add_style(style_indicator, lv.PART.INDICATOR)
+slider.add_style(style_pressed_color, lv.PART.INDICATOR | lv.STATE.PRESSED)
+slider.add_style(style_knob, lv.PART.KNOB)
+slider.add_style(style_pressed_color, lv.PART.KNOB | lv.STATE.PRESSED)
+
+slider.center()
+
diff --git a/lib/lvgl/examples/widgets/slider/lv_example_slider_3.c b/lib/lvgl/examples/widgets/slider/lv_example_slider_3.c
new file mode 100644
index 00000000..3194a1f8
--- /dev/null
+++ b/lib/lvgl/examples/widgets/slider/lv_example_slider_3.c
@@ -0,0 +1,56 @@
+#include "../../lv_examples.h"
+#if LV_USE_SLIDER && LV_BUILD_EXAMPLES
+
+static void slider_event_cb(lv_event_t * e);
+
+/**
+ * Show the current value when the slider is pressed by extending the drawer
+ *
+ */
+void lv_example_slider_3(void)
+{
+ /*Create a slider in the center of the display*/
+ lv_obj_t * slider;
+ slider = lv_slider_create(lv_scr_act());
+ lv_obj_center(slider);
+
+ lv_slider_set_mode(slider, LV_SLIDER_MODE_RANGE);
+ lv_slider_set_value(slider, 70, LV_ANIM_OFF);
+ lv_slider_set_left_value(slider, 20, LV_ANIM_OFF);
+
+ lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_ALL, NULL);
+ lv_obj_refresh_ext_draw_size(slider);
+}
+
+static void slider_event_cb(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+
+ /*Provide some extra space for the value*/
+ if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
+ lv_event_set_ext_draw_size(e, 50);
+ }
+ else if(code == LV_EVENT_DRAW_PART_END) {
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+ if(dsc->part == LV_PART_INDICATOR) {
+ char buf[16];
+ lv_snprintf(buf, sizeof(buf), "%d - %d", (int)lv_slider_get_left_value(obj), (int)lv_slider_get_value(obj));
+
+ lv_point_t label_size;
+ lv_txt_get_size(&label_size, buf, LV_FONT_DEFAULT, 0, 0, LV_COORD_MAX, 0);
+ lv_area_t label_area;
+ label_area.x1 = dsc->draw_area->x1 + lv_area_get_width(dsc->draw_area) / 2 - label_size.x / 2;
+ label_area.x2 = label_area.x1 + label_size.x;
+ label_area.y2 = dsc->draw_area->y1 - 10;
+ label_area.y1 = label_area.y2 - label_size.y;
+
+ lv_draw_label_dsc_t label_draw_dsc;
+ lv_draw_label_dsc_init(&label_draw_dsc);
+ label_draw_dsc.color = lv_color_hex3(0x888);
+ lv_draw_label(dsc->draw_ctx, &label_draw_dsc, &label_area, buf, NULL);
+ }
+ }
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/slider/lv_example_slider_3.py b/lib/lvgl/examples/widgets/slider/lv_example_slider_3.py
new file mode 100644
index 00000000..b96135ea
--- /dev/null
+++ b/lib/lvgl/examples/widgets/slider/lv_example_slider_3.py
@@ -0,0 +1,43 @@
+def slider_event_cb(e):
+ code = e.get_code()
+ obj = e.get_target()
+
+ # Provide some extra space for the value
+ if code == lv.EVENT.REFR_EXT_DRAW_SIZE:
+ e.set_ext_draw_size(50)
+
+ elif code == lv.EVENT.DRAW_PART_END:
+ # print("DRAW_PART_END")
+ dsc = lv.obj_draw_part_dsc_t.__cast__(e.get_param())
+ # print(dsc)
+ if dsc.part == lv.PART.INDICATOR:
+ label_text = "{:d} - {:d}".format(obj.get_left_value(),slider.get_value())
+ label_size = lv.point_t()
+ lv.txt_get_size(label_size, label_text, lv.font_default(), 0, 0, lv.COORD.MAX, 0)
+ # print(label_size.x,label_size.y)
+ label_area = lv.area_t()
+ label_area.x1 = dsc.draw_area.x1 + dsc.draw_area.get_width() // 2 - label_size.x // 2
+ label_area.x2 = label_area.x1 + label_size.x
+ label_area.y2 = dsc.draw_area.y1 - 10
+ label_area.y1 = label_area.y2 - label_size.y
+
+ label_draw_dsc = lv.draw_label_dsc_t()
+ label_draw_dsc.init()
+
+ dsc.draw_ctx.label(label_draw_dsc, label_area, label_text, None)
+#
+# Show the current value when the slider if pressed by extending the drawer
+#
+#
+#Create a slider in the center of the display
+
+slider = lv.slider(lv.scr_act())
+slider.center()
+
+slider.set_mode(lv.slider.MODE.RANGE)
+slider.set_value(70, lv.ANIM.OFF)
+slider.set_left_value(20, lv.ANIM.OFF)
+
+slider.add_event_cb(slider_event_cb, lv.EVENT.ALL, None)
+slider.refresh_ext_draw_size()
+
diff --git a/lib/lvgl/examples/widgets/span/index.rst b/lib/lvgl/examples/widgets/span/index.rst
new file mode 100644
index 00000000..470de97d
--- /dev/null
+++ b/lib/lvgl/examples/widgets/span/index.rst
@@ -0,0 +1,7 @@
+
+Span with custom styles
+""""""""""""""""""""""""
+
+.. lv_example:: widgets/span/lv_example_span_1
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/span/lv_example_span_1.c b/lib/lvgl/examples/widgets/span/lv_example_span_1.c
new file mode 100644
index 00000000..e09caed8
--- /dev/null
+++ b/lib/lvgl/examples/widgets/span/lv_example_span_1.c
@@ -0,0 +1,58 @@
+#include "../../lv_examples.h"
+#if LV_USE_SPAN && LV_BUILD_EXAMPLES
+
+/**
+ * Create span.
+ */
+void lv_example_span_1(void)
+{
+ static lv_style_t style;
+ lv_style_init(&style);
+ lv_style_set_border_width(&style, 1);
+ lv_style_set_border_color(&style, lv_palette_main(LV_PALETTE_ORANGE));
+ lv_style_set_pad_all(&style, 2);
+
+ lv_obj_t * spans = lv_spangroup_create(lv_scr_act());
+ lv_obj_set_width(spans, 300);
+ lv_obj_set_height(spans, 300);
+ lv_obj_center(spans);
+ lv_obj_add_style(spans, &style, 0);
+
+ lv_spangroup_set_align(spans, LV_TEXT_ALIGN_LEFT);
+ lv_spangroup_set_overflow(spans, LV_SPAN_OVERFLOW_CLIP);
+ lv_spangroup_set_indent(spans, 20);
+ lv_spangroup_set_mode(spans, LV_SPAN_MODE_BREAK);
+
+ lv_span_t * span = lv_spangroup_new_span(spans);
+ lv_span_set_text(span, "China is a beautiful country.");
+ lv_style_set_text_color(&span->style, lv_palette_main(LV_PALETTE_RED));
+ lv_style_set_text_decor(&span->style, LV_TEXT_DECOR_UNDERLINE);
+ lv_style_set_text_opa(&span->style, LV_OPA_50);
+
+ span = lv_spangroup_new_span(spans);
+ lv_span_set_text_static(span, "good good study, day day up.");
+#if LV_FONT_MONTSERRAT_24
+ lv_style_set_text_font(&span->style, &lv_font_montserrat_24);
+#endif
+ lv_style_set_text_color(&span->style, lv_palette_main(LV_PALETTE_GREEN));
+
+ span = lv_spangroup_new_span(spans);
+ lv_span_set_text_static(span, "LVGL is an open-source graphics library.");
+ lv_style_set_text_color(&span->style, lv_palette_main(LV_PALETTE_BLUE));
+
+ span = lv_spangroup_new_span(spans);
+ lv_span_set_text_static(span, "the boy no name.");
+ lv_style_set_text_color(&span->style, lv_palette_main(LV_PALETTE_GREEN));
+#if LV_FONT_MONTSERRAT_20
+ lv_style_set_text_font(&span->style, &lv_font_montserrat_20);
+#endif
+ lv_style_set_text_decor(&span->style, LV_TEXT_DECOR_UNDERLINE);
+
+ span = lv_spangroup_new_span(spans);
+ lv_span_set_text(span, "I have a dream that hope to come true.");
+ lv_style_set_text_decor(&span->style, LV_TEXT_DECOR_STRIKETHROUGH);
+
+ lv_spangroup_refr_mode(spans);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/span/lv_example_span_1.py b/lib/lvgl/examples/widgets/span/lv_example_span_1.py
new file mode 100644
index 00000000..d2b05b79
--- /dev/null
+++ b/lib/lvgl/examples/widgets/span/lv_example_span_1.py
@@ -0,0 +1,53 @@
+#
+# Create span
+#
+style = lv.style_t()
+style.init()
+style.set_border_width(1)
+style.set_border_color(lv.palette_main(lv.PALETTE.ORANGE))
+style.set_pad_all(2)
+
+spans = lv.spangroup(lv.scr_act())
+spans.set_width(300)
+spans.set_height(300)
+spans.center()
+spans.add_style(style, 0)
+
+spans.set_align(lv.TEXT_ALIGN.LEFT)
+spans.set_overflow(lv.SPAN_OVERFLOW.CLIP)
+spans.set_indent(20)
+spans.set_mode(lv.SPAN_MODE.BREAK)
+
+span = spans.new_span()
+span.set_text("china is a beautiful country.")
+span.style.set_text_color(lv.palette_main(lv.PALETTE.RED))
+span.style.set_text_decor(lv.TEXT_DECOR.STRIKETHROUGH | lv.TEXT_DECOR.UNDERLINE)
+span.style.set_text_opa(lv.OPA._30)
+
+span = spans.new_span()
+span.set_text_static("good good study, day day up.")
+#if LV_FONT_MONTSERRAT_24
+# lv_style_set_text_font(&span->style, &lv_font_montserrat_24);
+#endif
+span.style.set_text_color(lv.palette_main(lv.PALETTE.GREEN))
+
+span = spans.new_span()
+span.set_text_static("LVGL is an open-source graphics library.")
+span.style.set_text_color(lv.palette_main(lv.PALETTE.BLUE))
+
+span = spans.new_span()
+span.set_text_static("the boy no name.")
+span.style.set_text_color(lv.palette_main(lv.PALETTE.GREEN))
+#if LV_FONT_MONTSERRAT_20
+# lv_style_set_text_font(&span->style, &lv_font_montserrat_20);
+#endif
+span.style.set_text_decor(lv.TEXT_DECOR.UNDERLINE)
+
+span = spans.new_span()
+span.set_text("I have a dream that hope to come true.")
+
+spans.refr_mode()
+
+# lv_span_del(spans, span);
+# lv_obj_del(spans);
+
diff --git a/lib/lvgl/examples/widgets/spinbox/index.rst b/lib/lvgl/examples/widgets/spinbox/index.rst
new file mode 100644
index 00000000..4ccaddc0
--- /dev/null
+++ b/lib/lvgl/examples/widgets/spinbox/index.rst
@@ -0,0 +1,7 @@
+
+Simple Spinbox
+"""""""""""""""""""""""
+
+.. lv_example:: widgets/spinbox/lv_example_spinbox_1
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/spinbox/lv_example_spinbox_1.c b/lib/lvgl/examples/widgets/spinbox/lv_example_spinbox_1.c
new file mode 100644
index 00000000..2395aa4e
--- /dev/null
+++ b/lib/lvgl/examples/widgets/spinbox/lv_example_spinbox_1.c
@@ -0,0 +1,48 @@
+#include "../../lv_examples.h"
+#if LV_USE_SPINBOX && LV_BUILD_EXAMPLES
+
+static lv_obj_t * spinbox;
+
+
+static void lv_spinbox_increment_event_cb(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ if(code == LV_EVENT_SHORT_CLICKED || code == LV_EVENT_LONG_PRESSED_REPEAT) {
+ lv_spinbox_increment(spinbox);
+ }
+}
+
+static void lv_spinbox_decrement_event_cb(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ if(code == LV_EVENT_SHORT_CLICKED || code == LV_EVENT_LONG_PRESSED_REPEAT) {
+ lv_spinbox_decrement(spinbox);
+ }
+}
+
+
+void lv_example_spinbox_1(void)
+{
+ spinbox = lv_spinbox_create(lv_scr_act());
+ lv_spinbox_set_range(spinbox, -1000, 25000);
+ lv_spinbox_set_digit_format(spinbox, 5, 2);
+ lv_spinbox_step_prev(spinbox);
+ lv_obj_set_width(spinbox, 100);
+ lv_obj_center(spinbox);
+
+ lv_coord_t h = lv_obj_get_height(spinbox);
+
+ lv_obj_t * btn = lv_btn_create(lv_scr_act());
+ lv_obj_set_size(btn, h, h);
+ lv_obj_align_to(btn, spinbox, LV_ALIGN_OUT_RIGHT_MID, 5, 0);
+ lv_obj_set_style_bg_img_src(btn, LV_SYMBOL_PLUS, 0);
+ lv_obj_add_event_cb(btn, lv_spinbox_increment_event_cb, LV_EVENT_ALL, NULL);
+
+ btn = lv_btn_create(lv_scr_act());
+ lv_obj_set_size(btn, h, h);
+ lv_obj_align_to(btn, spinbox, LV_ALIGN_OUT_LEFT_MID, -5, 0);
+ lv_obj_set_style_bg_img_src(btn, LV_SYMBOL_MINUS, 0);
+ lv_obj_add_event_cb(btn, lv_spinbox_decrement_event_cb, LV_EVENT_ALL, NULL);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/spinbox/lv_example_spinbox_1.py b/lib/lvgl/examples/widgets/spinbox/lv_example_spinbox_1.py
new file mode 100644
index 00000000..fa00f9b5
--- /dev/null
+++ b/lib/lvgl/examples/widgets/spinbox/lv_example_spinbox_1.py
@@ -0,0 +1,30 @@
+def increment_event_cb(e):
+ code = e.get_code()
+ if code == lv.EVENT.SHORT_CLICKED or code == lv.EVENT.LONG_PRESSED_REPEAT:
+ spinbox.increment()
+
+def decrement_event_cb(e):
+ code = e.get_code()
+ if code == lv.EVENT.SHORT_CLICKED or code == lv.EVENT.LONG_PRESSED_REPEAT:
+ spinbox.decrement()
+
+spinbox = lv.spinbox(lv.scr_act())
+spinbox.set_range(-1000, 25000)
+spinbox.set_digit_format(5, 2)
+spinbox.step_prev()
+spinbox.set_width(100)
+spinbox.center()
+
+h = spinbox.get_height()
+
+btn = lv.btn(lv.scr_act())
+btn.set_size(h, h)
+btn.align_to(spinbox, lv.ALIGN.OUT_RIGHT_MID, 5, 0)
+btn.set_style_bg_img_src(lv.SYMBOL.PLUS, 0)
+btn.add_event_cb(increment_event_cb, lv.EVENT.ALL, None)
+
+btn = lv.btn(lv.scr_act())
+btn.set_size(h, h)
+btn.align_to(spinbox, lv.ALIGN.OUT_LEFT_MID, -5, 0)
+btn.set_style_bg_img_src(lv.SYMBOL.MINUS, 0)
+btn.add_event_cb(decrement_event_cb, lv.EVENT.ALL, None)
diff --git a/lib/lvgl/examples/widgets/spinner/index.rst b/lib/lvgl/examples/widgets/spinner/index.rst
new file mode 100644
index 00000000..c3cf2e77
--- /dev/null
+++ b/lib/lvgl/examples/widgets/spinner/index.rst
@@ -0,0 +1,7 @@
+
+Simple spinner
+""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/spinner/lv_example_spinner_1
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/spinner/lv_example_spinner_1.c b/lib/lvgl/examples/widgets/spinner/lv_example_spinner_1.c
new file mode 100644
index 00000000..e5410a86
--- /dev/null
+++ b/lib/lvgl/examples/widgets/spinner/lv_example_spinner_1.c
@@ -0,0 +1,12 @@
+#include "../../lv_examples.h"
+#if LV_USE_SPINNER && LV_BUILD_EXAMPLES
+
+void lv_example_spinner_1(void)
+{
+ /*Create a spinner*/
+ lv_obj_t * spinner = lv_spinner_create(lv_scr_act(), 1000, 60);
+ lv_obj_set_size(spinner, 100, 100);
+ lv_obj_center(spinner);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/spinner/lv_example_spinner_1.py b/lib/lvgl/examples/widgets/spinner/lv_example_spinner_1.py
new file mode 100644
index 00000000..8c342f35
--- /dev/null
+++ b/lib/lvgl/examples/widgets/spinner/lv_example_spinner_1.py
@@ -0,0 +1,6 @@
+# Create a spinner
+spinner = lv.spinner(lv.scr_act(), 1000, 60)
+spinner.set_size(100, 100)
+spinner.center()
+
+
diff --git a/lib/lvgl/examples/widgets/switch/index.rst b/lib/lvgl/examples/widgets/switch/index.rst
new file mode 100644
index 00000000..af97d218
--- /dev/null
+++ b/lib/lvgl/examples/widgets/switch/index.rst
@@ -0,0 +1,7 @@
+
+Simple Switch
+"""""""""""""""""""""""
+
+.. lv_example:: widgets/switch/lv_example_switch_1
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/switch/lv_example_switch_1.c b/lib/lvgl/examples/widgets/switch/lv_example_switch_1.c
new file mode 100644
index 00000000..f496a901
--- /dev/null
+++ b/lib/lvgl/examples/widgets/switch/lv_example_switch_1.c
@@ -0,0 +1,36 @@
+#include "../../lv_examples.h"
+#if LV_USE_SWITCH && LV_BUILD_EXAMPLES
+
+static void event_handler(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+ if(code == LV_EVENT_VALUE_CHANGED) {
+ LV_LOG_USER("State: %s\n", lv_obj_has_state(obj, LV_STATE_CHECKED) ? "On" : "Off");
+ }
+}
+
+void lv_example_switch_1(void)
+{
+ lv_obj_set_flex_flow(lv_scr_act(), LV_FLEX_FLOW_COLUMN);
+ lv_obj_set_flex_align(lv_scr_act(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
+
+ lv_obj_t * sw;
+
+ sw = lv_switch_create(lv_scr_act());
+ lv_obj_add_event_cb(sw, event_handler, LV_EVENT_ALL, NULL);
+
+ sw = lv_switch_create(lv_scr_act());
+ lv_obj_add_state(sw, LV_STATE_CHECKED);
+ lv_obj_add_event_cb(sw, event_handler, LV_EVENT_ALL, NULL);
+
+ sw = lv_switch_create(lv_scr_act());
+ lv_obj_add_state(sw, LV_STATE_DISABLED);
+ lv_obj_add_event_cb(sw, event_handler, LV_EVENT_ALL, NULL);
+
+ sw = lv_switch_create(lv_scr_act());
+ lv_obj_add_state(sw, LV_STATE_CHECKED | LV_STATE_DISABLED);
+ lv_obj_add_event_cb(sw, event_handler, LV_EVENT_ALL, NULL);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/switch/lv_example_switch_1.py b/lib/lvgl/examples/widgets/switch/lv_example_switch_1.py
new file mode 100644
index 00000000..e62a3538
--- /dev/null
+++ b/lib/lvgl/examples/widgets/switch/lv_example_switch_1.py
@@ -0,0 +1,28 @@
+def event_handler(e):
+ code = e.get_code()
+ obj = e.get_target()
+ if code == lv.EVENT.VALUE_CHANGED:
+ if obj.has_state(lv.STATE.CHECKED):
+ print("State: on")
+ else:
+ print("State: off")
+
+
+lv.scr_act().set_flex_flow(lv.FLEX_FLOW.COLUMN)
+lv.scr_act().set_flex_align(lv.FLEX_ALIGN.CENTER, lv.FLEX_ALIGN.CENTER, lv.FLEX_ALIGN.CENTER)
+
+sw = lv.switch(lv.scr_act())
+sw.add_event_cb(event_handler,lv.EVENT.ALL, None)
+
+sw = lv.switch(lv.scr_act())
+sw.add_state(lv.STATE.CHECKED)
+sw.add_event_cb(event_handler, lv.EVENT.ALL, None)
+
+sw = lv.switch(lv.scr_act())
+sw.add_state(lv.STATE.DISABLED)
+sw.add_event_cb(event_handler, lv.EVENT.ALL, None)
+
+sw = lv.switch(lv.scr_act())
+sw.add_state(lv.STATE.CHECKED | lv.STATE.DISABLED)
+sw.add_event_cb(event_handler, lv.EVENT.ALL, None)
+
diff --git a/lib/lvgl/examples/widgets/table/index.rst b/lib/lvgl/examples/widgets/table/index.rst
new file mode 100644
index 00000000..0072bbb0
--- /dev/null
+++ b/lib/lvgl/examples/widgets/table/index.rst
@@ -0,0 +1,14 @@
+
+
+Simple table
+"""""""""""""""""""""""
+
+.. lv_example:: widgets/table/lv_example_table_1
+ :language: c
+
+Lightweighted list from table
+""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/table/lv_example_table_2
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/table/lv_example_table_1.c b/lib/lvgl/examples/widgets/table/lv_example_table_1.c
new file mode 100644
index 00000000..dc776370
--- /dev/null
+++ b/lib/lvgl/examples/widgets/table/lv_example_table_1.c
@@ -0,0 +1,65 @@
+#include "../../lv_examples.h"
+#if LV_USE_TABLE && LV_BUILD_EXAMPLES
+
+static void draw_part_event_cb(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+ /*If the cells are drawn...*/
+ if(dsc->part == LV_PART_ITEMS) {
+ uint32_t row = dsc->id / lv_table_get_col_cnt(obj);
+ uint32_t col = dsc->id - row * lv_table_get_col_cnt(obj);
+
+ /*Make the texts in the first cell center aligned*/
+ if(row == 0) {
+ dsc->label_dsc->align = LV_TEXT_ALIGN_CENTER;
+ dsc->rect_dsc->bg_color = lv_color_mix(lv_palette_main(LV_PALETTE_BLUE), dsc->rect_dsc->bg_color, LV_OPA_20);
+ dsc->rect_dsc->bg_opa = LV_OPA_COVER;
+ }
+ /*In the first column align the texts to the right*/
+ else if(col == 0) {
+ dsc->label_dsc->align = LV_TEXT_ALIGN_RIGHT;
+ }
+
+ /*MAke every 2nd row grayish*/
+ if((row != 0 && row % 2) == 0) {
+ dsc->rect_dsc->bg_color = lv_color_mix(lv_palette_main(LV_PALETTE_GREY), dsc->rect_dsc->bg_color, LV_OPA_10);
+ dsc->rect_dsc->bg_opa = LV_OPA_COVER;
+ }
+ }
+}
+
+
+void lv_example_table_1(void)
+{
+ lv_obj_t * table = lv_table_create(lv_scr_act());
+
+ /*Fill the first column*/
+ lv_table_set_cell_value(table, 0, 0, "Name");
+ lv_table_set_cell_value(table, 1, 0, "Apple");
+ lv_table_set_cell_value(table, 2, 0, "Banana");
+ lv_table_set_cell_value(table, 3, 0, "Lemon");
+ lv_table_set_cell_value(table, 4, 0, "Grape");
+ lv_table_set_cell_value(table, 5, 0, "Melon");
+ lv_table_set_cell_value(table, 6, 0, "Peach");
+ lv_table_set_cell_value(table, 7, 0, "Nuts");
+
+ /*Fill the second column*/
+ lv_table_set_cell_value(table, 0, 1, "Price");
+ lv_table_set_cell_value(table, 1, 1, "$7");
+ lv_table_set_cell_value(table, 2, 1, "$4");
+ lv_table_set_cell_value(table, 3, 1, "$6");
+ lv_table_set_cell_value(table, 4, 1, "$2");
+ lv_table_set_cell_value(table, 5, 1, "$5");
+ lv_table_set_cell_value(table, 6, 1, "$1");
+ lv_table_set_cell_value(table, 7, 1, "$9");
+
+ /*Set a smaller height to the table. It'll make it scrollable*/
+ lv_obj_set_height(table, 200);
+ lv_obj_center(table);
+
+ /*Add an event callback to to apply some custom drawing*/
+ lv_obj_add_event_cb(table, draw_part_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/table/lv_example_table_1.py b/lib/lvgl/examples/widgets/table/lv_example_table_1.py
new file mode 100644
index 00000000..7faf0049
--- /dev/null
+++ b/lib/lvgl/examples/widgets/table/lv_example_table_1.py
@@ -0,0 +1,53 @@
+def draw_part_event_cb(e):
+ obj = e.get_target()
+ dsc = lv.obj_draw_part_dsc_t.__cast__(e.get_param())
+ # If the cells are drawn../
+ if dsc.part == lv.PART.ITEMS:
+ row = dsc.id // obj.get_col_cnt()
+ col = dsc.id - row * obj.get_col_cnt()
+
+ # Make the texts in the first cell center aligned
+ if row == 0:
+ dsc.label_dsc.align = lv.TEXT_ALIGN.CENTER
+ dsc.rect_dsc.bg_color = lv.palette_main(lv.PALETTE.BLUE).color_mix(dsc.rect_dsc.bg_color, lv.OPA._20)
+ dsc.rect_dsc.bg_opa = lv.OPA.COVER
+
+ # In the first column align the texts to the right
+ elif col == 0:
+ dsc.label_dsc.flag = lv.TEXT_ALIGN.RIGHT
+
+ # Make every 2nd row grayish
+ if row != 0 and (row % 2) == 0:
+ dsc.rect_dsc.bg_color = lv.palette_main(lv.PALETTE.GREY).color_mix(dsc.rect_dsc.bg_color, lv.OPA._10)
+ dsc.rect_dsc.bg_opa = lv.OPA.COVER
+
+
+table = lv.table(lv.scr_act())
+
+# Fill the first column
+table.set_cell_value(0, 0, "Name")
+table.set_cell_value(1, 0, "Apple")
+table.set_cell_value(2, 0, "Banana")
+table.set_cell_value(3, 0, "Lemon")
+table.set_cell_value(4, 0, "Grape")
+table.set_cell_value(5, 0, "Melon")
+table.set_cell_value(6, 0, "Peach")
+table.set_cell_value(7, 0, "Nuts")
+
+# Fill the second column
+table.set_cell_value(0, 1, "Price")
+table.set_cell_value(1, 1, "$7")
+table.set_cell_value(2, 1, "$4")
+table.set_cell_value(3, 1, "$6")
+table.set_cell_value(4, 1, "$2")
+table.set_cell_value(5, 1, "$5")
+table.set_cell_value(6, 1, "$1")
+table.set_cell_value(7, 1, "$9")
+
+# Set a smaller height to the table. It'll make it scrollable
+table.set_height(200)
+table.center()
+
+# Add an event callback to apply some custom drawing
+table.add_event_cb(draw_part_event_cb, lv.EVENT.DRAW_PART_BEGIN, None)
+
diff --git a/lib/lvgl/examples/widgets/table/lv_example_table_2.c b/lib/lvgl/examples/widgets/table/lv_example_table_2.c
new file mode 100644
index 00000000..bd1e933c
--- /dev/null
+++ b/lib/lvgl/examples/widgets/table/lv_example_table_2.c
@@ -0,0 +1,103 @@
+#include "../../lv_examples.h"
+#if LV_USE_TABLE && LV_BUILD_EXAMPLES
+
+#define ITEM_CNT 200
+
+static void draw_event_cb(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+ /*If the cells are drawn...*/
+ if(dsc->part == LV_PART_ITEMS) {
+ bool chk = lv_table_has_cell_ctrl(obj, dsc->id, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
+
+ lv_draw_rect_dsc_t rect_dsc;
+ lv_draw_rect_dsc_init(&rect_dsc);
+ rect_dsc.bg_color = chk ? lv_theme_get_color_primary(obj) : lv_palette_lighten(LV_PALETTE_GREY, 2);
+ rect_dsc.radius = LV_RADIUS_CIRCLE;
+
+ lv_area_t sw_area;
+ sw_area.x1 = dsc->draw_area->x2 - 50;
+ sw_area.x2 = sw_area.x1 + 40;
+ sw_area.y1 = dsc->draw_area->y1 + lv_area_get_height(dsc->draw_area) / 2 - 10;
+ sw_area.y2 = sw_area.y1 + 20;
+ lv_draw_rect(dsc->draw_ctx, &rect_dsc, &sw_area);
+
+ rect_dsc.bg_color = lv_color_white();
+ if(chk) {
+ sw_area.x2 -= 2;
+ sw_area.x1 = sw_area.x2 - 16;
+ }
+ else {
+ sw_area.x1 += 2;
+ sw_area.x2 = sw_area.x1 + 16;
+ }
+ sw_area.y1 += 2;
+ sw_area.y2 -= 2;
+ lv_draw_rect(dsc->draw_ctx, &rect_dsc, &sw_area);
+ }
+}
+
+static void change_event_cb(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+ uint16_t col;
+ uint16_t row;
+ lv_table_get_selected_cell(obj, &row, &col);
+ bool chk = lv_table_has_cell_ctrl(obj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
+ if(chk) lv_table_clear_cell_ctrl(obj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
+ else lv_table_add_cell_ctrl(obj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
+}
+
+
+/**
+ * A very light-weighted list created from table
+ */
+void lv_example_table_2(void)
+{
+ /*Measure memory usage*/
+ lv_mem_monitor_t mon1;
+ lv_mem_monitor(&mon1);
+
+ uint32_t t = lv_tick_get();
+
+ lv_obj_t * table = lv_table_create(lv_scr_act());
+
+ /*Set a smaller height to the table. It'll make it scrollable*/
+ lv_obj_set_size(table, LV_SIZE_CONTENT, 200);
+
+ lv_table_set_col_width(table, 0, 150);
+ lv_table_set_row_cnt(table, ITEM_CNT); /*Not required but avoids a lot of memory reallocation lv_table_set_set_value*/
+ lv_table_set_col_cnt(table, 1);
+
+ /*Don't make the cell pressed, we will draw something different in the event*/
+ lv_obj_remove_style(table, NULL, LV_PART_ITEMS | LV_STATE_PRESSED);
+
+ uint32_t i;
+ for(i = 0; i < ITEM_CNT; i++) {
+ lv_table_set_cell_value_fmt(table, i, 0, "Item %"LV_PRIu32, i + 1);
+ }
+
+ lv_obj_align(table, LV_ALIGN_CENTER, 0, -20);
+
+ /*Add an event callback to to apply some custom drawing*/
+ lv_obj_add_event_cb(table, draw_event_cb, LV_EVENT_DRAW_PART_END, NULL);
+ lv_obj_add_event_cb(table, change_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
+
+ lv_mem_monitor_t mon2;
+ lv_mem_monitor(&mon2);
+
+ uint32_t mem_used = mon1.free_size - mon2.free_size;
+
+ uint32_t elaps = lv_tick_elaps(t);
+
+ lv_obj_t * label = lv_label_create(lv_scr_act());
+ lv_label_set_text_fmt(label, "%"LV_PRIu32" items were created in %"LV_PRIu32" ms\n"
+ "using %"LV_PRIu32" bytes of memory",
+ ITEM_CNT, elaps, mem_used);
+
+ lv_obj_align(label, LV_ALIGN_BOTTOM_MID, 0, -10);
+
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/table/lv_example_table_2.py b/lib/lvgl/examples/widgets/table/lv_example_table_2.py
new file mode 100644
index 00000000..2da21613
--- /dev/null
+++ b/lib/lvgl/examples/widgets/table/lv_example_table_2.py
@@ -0,0 +1,95 @@
+from utime import ticks_ms
+import gc
+
+ITEM_CNT = 200
+
+def draw_event_cb(e):
+ obj = e.get_target()
+ dsc = lv.obj_draw_part_dsc_t.__cast__(e.get_param())
+ # If the cells are drawn...
+ if dsc.part == lv.PART.ITEMS:
+ chk = obj.has_cell_ctrl(dsc.id, 0, lv.table.CELL_CTRL.CUSTOM_1)
+
+ rect_dsc = lv.draw_rect_dsc_t()
+ rect_dsc.init()
+
+ if chk:
+ rect_dsc.bg_color = lv.theme_get_color_primary(obj)
+ else:
+ rect_dsc.bg_color = lv.palette_lighten(lv.PALETTE.GREY, 2)
+
+ rect_dsc.radius = lv.RADIUS.CIRCLE
+
+ sw_area = lv.area_t()
+ sw_area.x1 = dsc.draw_area.x2 - 50
+ sw_area.x2 = sw_area.x1 + 40
+ sw_area.y1 = dsc.draw_area.y1 + dsc.draw_area.get_height() // 2 - 10
+ sw_area.y2 = sw_area.y1 + 20
+ dsc.draw_ctx.rect(rect_dsc, sw_area)
+
+ rect_dsc.bg_color = lv.color_white()
+
+ if chk:
+ sw_area.x2 -= 2
+ sw_area.x1 = sw_area.x2 - 16
+ else:
+ sw_area.x1 += 2
+ sw_area.x2 = sw_area.x1 + 16
+ sw_area.y1 += 2
+ sw_area.y2 -= 2
+ dsc.draw_ctx.rect(rect_dsc, sw_area)
+
+def change_event_cb(e):
+ obj = e.get_target()
+ row = lv.C_Pointer()
+ col = lv.C_Pointer()
+ table.get_selected_cell(row, col)
+ # print("row: ",row.uint_val)
+
+ chk = table.has_cell_ctrl(row.uint_val, 0, lv.table.CELL_CTRL.CUSTOM_1)
+ if chk:
+ table.clear_cell_ctrl(row.uint_val, 0, lv.table.CELL_CTRL.CUSTOM_1)
+ else:
+ table.add_cell_ctrl(row.uint_val, 0, lv.table.CELL_CTRL.CUSTOM_1)
+
+#
+# A very light-weighted list created from table
+#
+
+# Measure memory usage
+gc.enable()
+gc.collect()
+mem_free = gc.mem_free()
+print("mem_free: ", mem_free)
+t = ticks_ms()
+print("ticks: ", t)
+table = lv.table(lv.scr_act())
+
+# Set a smaller height to the table. It'll make it scrollable
+table.set_size(150, 200)
+
+table.set_col_width(0, 150)
+table.set_row_cnt(ITEM_CNT) # Not required but avoids a lot of memory reallocation lv_table_set_set_value
+table.set_col_cnt(1)
+
+# Don't make the cell pressed, we will draw something different in the event
+table.remove_style(None, lv.PART.ITEMS | lv.STATE.PRESSED)
+
+for i in range(ITEM_CNT):
+ table.set_cell_value(i, 0, "Item " + str(i+1))
+
+table.align(lv.ALIGN.CENTER, 0, -20)
+
+# Add an event callback to apply some custom drawing
+table.add_event_cb(draw_event_cb, lv.EVENT.DRAW_PART_END, None)
+table.add_event_cb(change_event_cb, lv.EVENT.VALUE_CHANGED, None)
+
+gc.collect()
+mem_used = mem_free - gc.mem_free()
+elaps = ticks_ms()-t
+
+label = lv.label(lv.scr_act())
+label.set_text(str(ITEM_CNT) + " items were created in " + str(elaps) + " ms\n using " + str(mem_used) + " bytes of memory")
+#label.set_text(str(ITEM_CNT) + " items were created in " + str(elaps) + " ms")
+
+label.align(lv.ALIGN.BOTTOM_MID, 0, -10)
diff --git a/lib/lvgl/examples/widgets/tabview/index.rst b/lib/lvgl/examples/widgets/tabview/index.rst
new file mode 100644
index 00000000..46851355
--- /dev/null
+++ b/lib/lvgl/examples/widgets/tabview/index.rst
@@ -0,0 +1,14 @@
+
+Simple Tabview
+"""""""""""""""""""""""
+
+.. lv_example:: widgets/tabview/lv_example_tabview_1
+ :language: c
+
+Tabs on the left, styling and no scrolling
+"""""""""""""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/tabview/lv_example_tabview_2
+ :language: c
+
+
diff --git a/lib/lvgl/examples/widgets/tabview/lv_example_tabview_1.c b/lib/lvgl/examples/widgets/tabview/lv_example_tabview_1.c
new file mode 100644
index 00000000..570a7b82
--- /dev/null
+++ b/lib/lvgl/examples/widgets/tabview/lv_example_tabview_1.c
@@ -0,0 +1,42 @@
+#include "../../lv_examples.h"
+#if LV_USE_TABVIEW && LV_BUILD_EXAMPLES
+
+void lv_example_tabview_1(void)
+{
+ /*Create a Tab view object*/
+ lv_obj_t * tabview;
+ tabview = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, 50);
+
+ /*Add 3 tabs (the tabs are page (lv_page) and can be scrolled*/
+ lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Tab 1");
+ lv_obj_t * tab2 = lv_tabview_add_tab(tabview, "Tab 2");
+ lv_obj_t * tab3 = lv_tabview_add_tab(tabview, "Tab 3");
+
+ /*Add content to the tabs*/
+ lv_obj_t * label = lv_label_create(tab1);
+ lv_label_set_text(label, "This the first tab\n\n"
+ "If the content\n"
+ "of a tab\n"
+ "becomes too\n"
+ "longer\n"
+ "than the\n"
+ "container\n"
+ "then it\n"
+ "automatically\n"
+ "becomes\n"
+ "scrollable.\n"
+ "\n"
+ "\n"
+ "\n"
+ "Can you see it?");
+
+ label = lv_label_create(tab2);
+ lv_label_set_text(label, "Second tab");
+
+ label = lv_label_create(tab3);
+ lv_label_set_text(label, "Third tab");
+
+ lv_obj_scroll_to_view_recursive(label, LV_ANIM_ON);
+
+}
+#endif
diff --git a/lib/lvgl/examples/widgets/tabview/lv_example_tabview_1.py b/lib/lvgl/examples/widgets/tabview/lv_example_tabview_1.py
new file mode 100644
index 00000000..d5e219a7
--- /dev/null
+++ b/lib/lvgl/examples/widgets/tabview/lv_example_tabview_1.py
@@ -0,0 +1,35 @@
+# Create a Tab view object
+tabview = lv.tabview(lv.scr_act(), lv.DIR.TOP, 50)
+
+# Add 3 tabs (the tabs are page (lv_page) and can be scrolled
+tab1 = tabview.add_tab("Tab 1")
+tab2 = tabview.add_tab("Tab 2")
+tab3 = tabview.add_tab("Tab 3")
+
+# Add content to the tabs
+label = lv.label(tab1)
+label.set_text("""This the first tab
+
+If the content
+of a tab
+becomes too
+longer
+than the
+container
+then it
+automatically
+becomes
+scrollable.
+
+
+
+Can you see it?""")
+
+label = lv.label(tab2)
+label.set_text("Second tab")
+
+label = lv.label(tab3)
+label.set_text("Third tab");
+
+label.scroll_to_view_recursive(lv.ANIM.ON)
+
diff --git a/lib/lvgl/examples/widgets/tabview/lv_example_tabview_2.c b/lib/lvgl/examples/widgets/tabview/lv_example_tabview_2.c
new file mode 100644
index 00000000..02660426
--- /dev/null
+++ b/lib/lvgl/examples/widgets/tabview/lv_example_tabview_2.c
@@ -0,0 +1,56 @@
+#include "../../lv_examples.h"
+#if LV_USE_TABVIEW && LV_BUILD_EXAMPLES
+
+static void scroll_begin_event(lv_event_t * e)
+{
+ /*Disable the scroll animations. Triggered when a tab button is clicked */
+ if(lv_event_get_code(e) == LV_EVENT_SCROLL_BEGIN) {
+ lv_anim_t * a = lv_event_get_param(e);
+ if(a) a->time = 0;
+ }
+}
+
+void lv_example_tabview_2(void)
+{
+ /*Create a Tab view object*/
+ lv_obj_t * tabview;
+ tabview = lv_tabview_create(lv_scr_act(), LV_DIR_LEFT, 80);
+ lv_obj_add_event_cb(lv_tabview_get_content(tabview), scroll_begin_event, LV_EVENT_SCROLL_BEGIN, NULL);
+
+ lv_obj_set_style_bg_color(tabview, lv_palette_lighten(LV_PALETTE_RED, 2), 0);
+
+ lv_obj_t * tab_btns = lv_tabview_get_tab_btns(tabview);
+ lv_obj_set_style_bg_color(tab_btns, lv_palette_darken(LV_PALETTE_GREY, 3), 0);
+ lv_obj_set_style_text_color(tab_btns, lv_palette_lighten(LV_PALETTE_GREY, 5), 0);
+ lv_obj_set_style_border_side(tab_btns, LV_BORDER_SIDE_RIGHT, LV_PART_ITEMS | LV_STATE_CHECKED);
+
+
+ /*Add 3 tabs (the tabs are page (lv_page) and can be scrolled*/
+ lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Tab 1");
+ lv_obj_t * tab2 = lv_tabview_add_tab(tabview, "Tab 2");
+ lv_obj_t * tab3 = lv_tabview_add_tab(tabview, "Tab 3");
+ lv_obj_t * tab4 = lv_tabview_add_tab(tabview, "Tab 4");
+ lv_obj_t * tab5 = lv_tabview_add_tab(tabview, "Tab 5");
+
+ lv_obj_set_style_bg_color(tab2, lv_palette_lighten(LV_PALETTE_AMBER, 3), 0);
+ lv_obj_set_style_bg_opa(tab2, LV_OPA_COVER, 0);
+
+ /*Add content to the tabs*/
+ lv_obj_t * label = lv_label_create(tab1);
+ lv_label_set_text(label, "First tab");
+
+ label = lv_label_create(tab2);
+ lv_label_set_text(label, "Second tab");
+
+ label = lv_label_create(tab3);
+ lv_label_set_text(label, "Third tab");
+
+ label = lv_label_create(tab4);
+ lv_label_set_text(label, "Forth tab");
+
+ label = lv_label_create(tab5);
+ lv_label_set_text(label, "Fifth tab");
+
+ lv_obj_clear_flag(lv_tabview_get_content(tabview), LV_OBJ_FLAG_SCROLLABLE);
+}
+#endif
diff --git a/lib/lvgl/examples/widgets/tabview/lv_example_tabview_2.py b/lib/lvgl/examples/widgets/tabview/lv_example_tabview_2.py
new file mode 100644
index 00000000..f1604be9
--- /dev/null
+++ b/lib/lvgl/examples/widgets/tabview/lv_example_tabview_2.py
@@ -0,0 +1,48 @@
+def scroll_begin_event(e):
+
+ #Disable the scroll animations. Triggered when a tab button is clicked */
+ if e.get_code() == lv.EVENT.SCROLL_BEGIN:
+ a = lv.anim_t.__cast__(e.get_param())
+ if a:
+ a.time = 0
+
+# Create a Tab view object
+tabview = lv.tabview(lv.scr_act(), lv.DIR.LEFT, 80)
+tabview.get_content().add_event_cb(scroll_begin_event, lv.EVENT.SCROLL_BEGIN, None)
+
+tabview.set_style_bg_color(lv.palette_lighten(lv.PALETTE.RED, 2), 0)
+
+tab_btns = tabview.get_tab_btns()
+tab_btns.set_style_bg_color(lv.palette_darken(lv.PALETTE.GREY, 3), 0)
+tab_btns.set_style_text_color(lv.palette_lighten(lv.PALETTE.GREY, 5), 0)
+tab_btns.set_style_border_side(lv.BORDER_SIDE.RIGHT, lv.PART.ITEMS | lv.STATE.CHECKED)
+
+
+# Add 3 tabs (the tabs are page (lv_page) and can be scrolled
+tab1 = tabview.add_tab("Tab 1")
+tab2 = tabview.add_tab("Tab 2")
+tab3 = tabview.add_tab("Tab 3")
+tab4 = tabview.add_tab("Tab 4")
+tab5 = tabview.add_tab("Tab 5")
+
+tab2.set_style_bg_color(lv.palette_lighten(lv.PALETTE.AMBER, 3), 0)
+tab2.set_style_bg_opa(lv.OPA.COVER, 0)
+
+# Add content to the tabs
+label = lv.label(tab1)
+label.set_text("First tab")
+
+label = lv.label(tab2)
+label.set_text("Second tab")
+
+label = lv.label(tab3)
+label.set_text("Third tab")
+
+label = lv.label(tab4)
+label.set_text("Forth tab")
+
+label = lv.label(tab5)
+label.set_text("Fifth tab")
+
+tabview.get_content().clear_flag(lv.obj.FLAG.SCROLLABLE)
+
diff --git a/lib/lvgl/examples/widgets/textarea/index.rst b/lib/lvgl/examples/widgets/textarea/index.rst
new file mode 100644
index 00000000..9bb7bb51
--- /dev/null
+++ b/lib/lvgl/examples/widgets/textarea/index.rst
@@ -0,0 +1,20 @@
+
+Simple Text area
+"""""""""""""""""""""""
+
+.. lv_example:: widgets/textarea/lv_example_textarea_1
+ :language: c
+
+
+Text area with password field
+"""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/textarea/lv_example_textarea_2
+ :language: c
+
+Text auto-formatting
+"""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/textarea/lv_example_textarea_3
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/textarea/lv_example_textarea_1.c b/lib/lvgl/examples/widgets/textarea/lv_example_textarea_1.c
new file mode 100644
index 00000000..d8689cb9
--- /dev/null
+++ b/lib/lvgl/examples/widgets/textarea/lv_example_textarea_1.c
@@ -0,0 +1,44 @@
+#include "../../lv_examples.h"
+#if LV_USE_TEXTAREA && LV_BUILD_EXAMPLES
+
+static void textarea_event_handler(lv_event_t * e)
+{
+ lv_obj_t * ta = lv_event_get_target(e);
+ LV_LOG_USER("Enter was pressed. The current text is: %s", lv_textarea_get_text(ta));
+}
+
+static void btnm_event_handler(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+ lv_obj_t * ta = lv_event_get_user_data(e);
+ const char * txt = lv_btnmatrix_get_btn_text(obj, lv_btnmatrix_get_selected_btn(obj));
+
+ if(strcmp(txt, LV_SYMBOL_BACKSPACE) == 0) lv_textarea_del_char(ta);
+ else if(strcmp(txt, LV_SYMBOL_NEW_LINE) == 0) lv_event_send(ta, LV_EVENT_READY, NULL);
+ else lv_textarea_add_text(ta, txt);
+
+}
+
+void lv_example_textarea_1(void)
+{
+ lv_obj_t * ta = lv_textarea_create(lv_scr_act());
+ lv_textarea_set_one_line(ta, true);
+ lv_obj_align(ta, LV_ALIGN_TOP_MID, 0, 10);
+ lv_obj_add_event_cb(ta, textarea_event_handler, LV_EVENT_READY, ta);
+ lv_obj_add_state(ta, LV_STATE_FOCUSED); /*To be sure the cursor is visible*/
+
+ static const char * btnm_map[] = {"1", "2", "3", "\n",
+ "4", "5", "6", "\n",
+ "7", "8", "9", "\n",
+ LV_SYMBOL_BACKSPACE, "0", LV_SYMBOL_NEW_LINE, ""
+ };
+
+ lv_obj_t * btnm = lv_btnmatrix_create(lv_scr_act());
+ lv_obj_set_size(btnm, 200, 150);
+ lv_obj_align(btnm, LV_ALIGN_BOTTOM_MID, 0, -10);
+ lv_obj_add_event_cb(btnm, btnm_event_handler, LV_EVENT_VALUE_CHANGED, ta);
+ lv_obj_clear_flag(btnm, LV_OBJ_FLAG_CLICK_FOCUSABLE); /*To keep the text area focused on button clicks*/
+ lv_btnmatrix_set_map(btnm, btnm_map);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/textarea/lv_example_textarea_1.py b/lib/lvgl/examples/widgets/textarea/lv_example_textarea_1.py
new file mode 100644
index 00000000..c5571889
--- /dev/null
+++ b/lib/lvgl/examples/widgets/textarea/lv_example_textarea_1.py
@@ -0,0 +1,32 @@
+def textarea_event_handler(e, ta):
+ print("Enter was pressed. The current text is: " + ta.get_text())
+
+
+def btnm_event_handler(e, ta):
+ obj = e.get_target()
+ txt = obj.get_btn_text(obj.get_selected_btn())
+ if txt == lv.SYMBOL.BACKSPACE:
+ ta.del_char()
+ elif txt == lv.SYMBOL.NEW_LINE:
+ lv.event_send(ta, lv.EVENT.READY, None)
+ elif txt:
+ ta.add_text(txt)
+
+
+ta = lv.textarea(lv.scr_act())
+ta.set_one_line(True)
+ta.align(lv.ALIGN.TOP_MID, 0, 10)
+ta.add_event_cb(lambda e: textarea_event_handler(e, ta), lv.EVENT.READY, None)
+ta.add_state(lv.STATE.FOCUSED) # To be sure the cursor is visible
+
+btnm_map = ["1", "2", "3", "\n",
+ "4", "5", "6", "\n",
+ "7", "8", "9", "\n",
+ lv.SYMBOL.BACKSPACE, "0", lv.SYMBOL.NEW_LINE, ""]
+
+btnm = lv.btnmatrix(lv.scr_act())
+btnm.set_size(200, 150)
+btnm.align(lv.ALIGN.BOTTOM_MID, 0, -10)
+btnm.add_event_cb(lambda e: btnm_event_handler(e, ta), lv.EVENT.VALUE_CHANGED, None)
+btnm.clear_flag(lv.obj.FLAG.CLICK_FOCUSABLE) # To keep the text area focused on button clicks
+btnm.set_map(btnm_map)
diff --git a/lib/lvgl/examples/widgets/textarea/lv_example_textarea_2.c b/lib/lvgl/examples/widgets/textarea/lv_example_textarea_2.c
new file mode 100644
index 00000000..0a915caa
--- /dev/null
+++ b/lib/lvgl/examples/widgets/textarea/lv_example_textarea_2.c
@@ -0,0 +1,59 @@
+#include "../../lv_examples.h"
+#if LV_USE_TEXTAREA && LV_USE_KEYBOARD && LV_BUILD_EXAMPLES
+
+static void ta_event_cb(lv_event_t * e);
+
+static lv_obj_t * kb;
+
+void lv_example_textarea_2(void)
+{
+ /*Create the password box*/
+ lv_obj_t * pwd_ta = lv_textarea_create(lv_scr_act());
+ lv_textarea_set_text(pwd_ta, "");
+ lv_textarea_set_password_mode(pwd_ta, true);
+ lv_textarea_set_one_line(pwd_ta, true);
+ lv_obj_set_width(pwd_ta, lv_pct(40));
+ lv_obj_set_pos(pwd_ta, 5, 20);
+ lv_obj_add_event_cb(pwd_ta, ta_event_cb, LV_EVENT_ALL, NULL);
+
+ /*Create a label and position it above the text box*/
+ lv_obj_t * pwd_label = lv_label_create(lv_scr_act());
+ lv_label_set_text(pwd_label, "Password:");
+ lv_obj_align_to(pwd_label, pwd_ta, LV_ALIGN_OUT_TOP_LEFT, 0, 0);
+
+ /*Create the one-line mode text area*/
+ lv_obj_t * text_ta = lv_textarea_create(lv_scr_act());
+ lv_textarea_set_one_line(text_ta, true);
+ lv_textarea_set_password_mode(text_ta, false);
+ lv_obj_set_width(text_ta, lv_pct(40));
+ lv_obj_add_event_cb(text_ta, ta_event_cb, LV_EVENT_ALL, NULL);
+ lv_obj_align(text_ta, LV_ALIGN_TOP_RIGHT, -5, 20);
+
+
+ /*Create a label and position it above the text box*/
+ lv_obj_t * oneline_label = lv_label_create(lv_scr_act());
+ lv_label_set_text(oneline_label, "Text:");
+ lv_obj_align_to(oneline_label, text_ta, LV_ALIGN_OUT_TOP_LEFT, 0, 0);
+
+ /*Create a keyboard*/
+ kb = lv_keyboard_create(lv_scr_act());
+ lv_obj_set_size(kb, LV_HOR_RES, LV_VER_RES / 2);
+
+ lv_keyboard_set_textarea(kb, pwd_ta); /*Focus it on one of the text areas to start*/
+}
+
+static void ta_event_cb(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * ta = lv_event_get_target(e);
+ if(code == LV_EVENT_CLICKED || code == LV_EVENT_FOCUSED) {
+ /*Focus on the clicked text area*/
+ if(kb != NULL) lv_keyboard_set_textarea(kb, ta);
+ }
+
+ else if(code == LV_EVENT_READY) {
+ LV_LOG_USER("Ready, current text: %s", lv_textarea_get_text(ta));
+ }
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/textarea/lv_example_textarea_2.py b/lib/lvgl/examples/widgets/textarea/lv_example_textarea_2.py
new file mode 100644
index 00000000..b418861d
--- /dev/null
+++ b/lib/lvgl/examples/widgets/textarea/lv_example_textarea_2.py
@@ -0,0 +1,49 @@
+def ta_event_cb(e):
+ code = e.get_code()
+ ta = e.get_target()
+ if code == lv.EVENT.CLICKED or code == lv.EVENT.FOCUSED:
+ # Focus on the clicked text area
+ if kb != None:
+ kb.set_textarea(ta)
+
+ elif code == lv.EVENT.READY:
+ print("Ready, current text: " + ta.get_text())
+
+
+# Create the password box
+LV_HOR_RES = lv.scr_act().get_disp().driver.hor_res
+LV_VER_RES = lv.scr_act().get_disp().driver.ver_res
+
+pwd_ta = lv.textarea(lv.scr_act())
+pwd_ta.set_text("")
+pwd_ta.set_password_mode(True)
+pwd_ta.set_one_line(True)
+pwd_ta.set_width(LV_HOR_RES // 2 - 20)
+pwd_ta.set_pos(5, 20)
+pwd_ta.add_event_cb(ta_event_cb, lv.EVENT.ALL, None)
+
+# Create a label and position it above the text box
+pwd_label = lv.label(lv.scr_act())
+pwd_label.set_text("Password:")
+pwd_label.align_to(pwd_ta, lv.ALIGN.OUT_TOP_LEFT, 0, 0)
+
+# Create the one-line mode text area
+text_ta = lv.textarea(lv.scr_act())
+text_ta.set_width(LV_HOR_RES // 2 - 20)
+text_ta.set_one_line(True)
+text_ta.add_event_cb(ta_event_cb, lv.EVENT.ALL, None)
+text_ta.set_password_mode(False)
+
+text_ta.align(lv.ALIGN.TOP_RIGHT, -5, 20)
+
+# Create a label and position it above the text box
+oneline_label = lv.label(lv.scr_act())
+oneline_label.set_text("Text:")
+oneline_label.align_to(text_ta, lv.ALIGN.OUT_TOP_LEFT, 0, 0)
+
+# Create a keyboard
+kb = lv.keyboard(lv.scr_act())
+kb.set_size(LV_HOR_RES, LV_VER_RES // 2)
+
+kb.set_textarea(pwd_ta) # Focus it on one of the text areas to start
+
diff --git a/lib/lvgl/examples/widgets/textarea/lv_example_textarea_3.c b/lib/lvgl/examples/widgets/textarea/lv_example_textarea_3.c
new file mode 100644
index 00000000..d3a453a0
--- /dev/null
+++ b/lib/lvgl/examples/widgets/textarea/lv_example_textarea_3.c
@@ -0,0 +1,41 @@
+#include "../../lv_examples.h"
+#if LV_USE_TEXTAREA && LV_USE_KEYBOARD && LV_BUILD_EXAMPLES
+
+static void ta_event_cb(lv_event_t * e);
+
+static lv_obj_t * kb;
+
+/**
+ * Automatically format text like a clock. E.g. "12:34"
+ * Add the ':' automatically.
+ */
+void lv_example_textarea_3(void)
+{
+ /*Create the text area*/
+ lv_obj_t * ta = lv_textarea_create(lv_scr_act());
+ lv_obj_add_event_cb(ta, ta_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
+ lv_textarea_set_accepted_chars(ta, "0123456789:");
+ lv_textarea_set_max_length(ta, 5);
+ lv_textarea_set_one_line(ta, true);
+ lv_textarea_set_text(ta, "");
+
+ /*Create a keyboard*/
+ kb = lv_keyboard_create(lv_scr_act());
+ lv_obj_set_size(kb, LV_HOR_RES, LV_VER_RES / 2);
+ lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_NUMBER);
+ lv_keyboard_set_textarea(kb, ta);
+}
+
+static void ta_event_cb(lv_event_t * e)
+{
+ lv_obj_t * ta = lv_event_get_target(e);
+ const char * txt = lv_textarea_get_text(ta);
+ if(txt[0] >= '0' && txt[0] <= '9' &&
+ txt[1] >= '0' && txt[1] <= '9' &&
+ txt[2] != ':') {
+ lv_textarea_set_cursor_pos(ta, 2);
+ lv_textarea_add_char(ta, ':');
+ }
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/textarea/lv_example_textarea_3.py b/lib/lvgl/examples/widgets/textarea/lv_example_textarea_3.py
new file mode 100644
index 00000000..71d7c2d9
--- /dev/null
+++ b/lib/lvgl/examples/widgets/textarea/lv_example_textarea_3.py
@@ -0,0 +1,50 @@
+def ta_event_cb(e):
+ ta = e.get_target()
+ txt = ta.get_text()
+ # print(txt)
+ pos = ta.get_cursor_pos()
+ # print("cursor pos: ",pos)
+ # find position of ":" in text
+ colon_pos= txt.find(":")
+ # if there are more than 2 digits before the colon, remove the last one entered
+ if colon_pos == 3:
+ ta.del_char()
+ if colon_pos != -1:
+ # if there are more than 3 digits after the ":" remove the last one entered
+ rest = txt[colon_pos:]
+ if len(rest) > 3:
+ ta.del_char()
+
+ if len(txt) < 2:
+ return
+ if ":" in txt:
+ return
+ if txt[0] >= '0' and txt[0] <= '9' and \
+ txt[1] >= '0' and txt[1] <= '9':
+ if len(txt) == 2 or txt[2] != ':' :
+ ta.set_cursor_pos(2)
+ ta.add_char(ord(':'))
+#
+# Automatically format text like a clock. E.g. "12:34"
+# Add the ':' automatically
+#
+# Create the text area
+
+LV_HOR_RES = lv.scr_act().get_disp().driver.hor_res
+LV_VER_RES = lv.scr_act().get_disp().driver.ver_res
+
+ta = lv.textarea(lv.scr_act())
+ta.add_event_cb(ta_event_cb, lv.EVENT.VALUE_CHANGED, None)
+ta.set_accepted_chars("0123456789:")
+ta.set_max_length(5)
+ta.set_one_line(True)
+ta.set_text("")
+ta.add_state(lv.STATE.FOCUSED)
+
+# Create a keyboard
+kb = lv.keyboard(lv.scr_act())
+kb.set_size(LV_HOR_RES, LV_VER_RES // 2)
+kb.set_mode(lv.keyboard.MODE.NUMBER)
+kb.set_textarea(ta)
+
+
diff --git a/lib/lvgl/examples/widgets/tileview/index.rst b/lib/lvgl/examples/widgets/tileview/index.rst
new file mode 100644
index 00000000..10910f4c
--- /dev/null
+++ b/lib/lvgl/examples/widgets/tileview/index.rst
@@ -0,0 +1,7 @@
+
+Tileview with content
+"""""""""""""""""""""""""""
+
+.. lv_example:: widgets/tileview/lv_example_tileview_1
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/tileview/lv_example_tileview_1.c b/lib/lvgl/examples/widgets/tileview/lv_example_tileview_1.c
new file mode 100644
index 00000000..8f91d279
--- /dev/null
+++ b/lib/lvgl/examples/widgets/tileview/lv_example_tileview_1.c
@@ -0,0 +1,49 @@
+#include "../../lv_examples.h"
+#if LV_USE_TILEVIEW && LV_BUILD_EXAMPLES
+
+/**
+ * Create a 2x2 tile view and allow scrolling only in an "L" shape.
+ * Demonstrate scroll chaining with a long list that
+ * scrolls the tile view when it can't be scrolled further.
+ */
+void lv_example_tileview_1(void)
+{
+ lv_obj_t * tv = lv_tileview_create(lv_scr_act());
+
+ /*Tile1: just a label*/
+ lv_obj_t * tile1 = lv_tileview_add_tile(tv, 0, 0, LV_DIR_BOTTOM);
+ lv_obj_t * label = lv_label_create(tile1);
+ lv_label_set_text(label, "Scroll down");
+ lv_obj_center(label);
+
+
+ /*Tile2: a button*/
+ lv_obj_t * tile2 = lv_tileview_add_tile(tv, 0, 1, LV_DIR_TOP | LV_DIR_RIGHT);
+
+ lv_obj_t * btn = lv_btn_create(tile2);
+
+ label = lv_label_create(btn);
+ lv_label_set_text(label, "Scroll up or right");
+
+ lv_obj_set_size(btn, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
+ lv_obj_center(btn);
+
+ /*Tile3: a list*/
+ lv_obj_t * tile3 = lv_tileview_add_tile(tv, 1, 1, LV_DIR_LEFT);
+ lv_obj_t * list = lv_list_create(tile3);
+ lv_obj_set_size(list, LV_PCT(100), LV_PCT(100));
+
+ lv_list_add_btn(list, NULL, "One");
+ lv_list_add_btn(list, NULL, "Two");
+ lv_list_add_btn(list, NULL, "Three");
+ lv_list_add_btn(list, NULL, "Four");
+ lv_list_add_btn(list, NULL, "Five");
+ lv_list_add_btn(list, NULL, "Six");
+ lv_list_add_btn(list, NULL, "Seven");
+ lv_list_add_btn(list, NULL, "Eight");
+ lv_list_add_btn(list, NULL, "Nine");
+ lv_list_add_btn(list, NULL, "Ten");
+
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/tileview/lv_example_tileview_1.py b/lib/lvgl/examples/widgets/tileview/lv_example_tileview_1.py
new file mode 100644
index 00000000..2e8b67c3
--- /dev/null
+++ b/lib/lvgl/examples/widgets/tileview/lv_example_tileview_1.py
@@ -0,0 +1,39 @@
+#
+# Create a 2x2 tile view and allow scrolling only in an "L" shape.
+# Demonstrate scroll chaining with a long list that
+# scrolls the tile view when it can't be scrolled further.
+#
+tv = lv.tileview(lv.scr_act())
+
+# Tile1: just a label
+tile1 = tv.add_tile(0, 0, lv.DIR.BOTTOM)
+label = lv.label(tile1)
+label.set_text("Scroll down")
+label.center()
+
+# Tile2: a button
+tile2 = tv.add_tile(0, 1, lv.DIR.TOP | lv.DIR.RIGHT)
+
+btn = lv.btn(tile2)
+
+label = lv.label(btn)
+label.set_text("Scroll up or right")
+
+btn.set_size(lv.SIZE.CONTENT, lv.SIZE.CONTENT)
+btn.center()
+
+# Tile3: a list
+tile3 = tv.add_tile(1, 1, lv.DIR.LEFT)
+list = lv.list(tile3)
+list.set_size(lv.pct(100), lv.pct(100))
+
+list.add_btn(None, "One")
+list.add_btn(None, "Two")
+list.add_btn(None, "Three")
+list.add_btn(None, "Four")
+list.add_btn(None, "Five")
+list.add_btn(None, "Six")
+list.add_btn(None, "Seven")
+list.add_btn(None, "Eight")
+list.add_btn(None, "Nine")
+list.add_btn(None, "Ten")
diff --git a/lib/lvgl/examples/widgets/win/index.rst b/lib/lvgl/examples/widgets/win/index.rst
new file mode 100644
index 00000000..2f6fc3a2
--- /dev/null
+++ b/lib/lvgl/examples/widgets/win/index.rst
@@ -0,0 +1,7 @@
+
+Simple window
+"""""""""""""""
+
+.. lv_example:: widgets/win/lv_example_win_1
+ :language: c
+
diff --git a/lib/lvgl/examples/widgets/win/lv_example_win_1.c b/lib/lvgl/examples/widgets/win/lv_example_win_1.c
new file mode 100644
index 00000000..4df0bff7
--- /dev/null
+++ b/lib/lvgl/examples/widgets/win/lv_example_win_1.c
@@ -0,0 +1,45 @@
+#include "../../lv_examples.h"
+#if LV_USE_WIN && LV_BUILD_EXAMPLES
+
+
+static void event_handler(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+ LV_LOG_USER("Button %d clicked", (int)lv_obj_get_index(obj));
+}
+
+void lv_example_win_1(void)
+{
+ lv_obj_t * win = lv_win_create(lv_scr_act(), 40);
+ lv_obj_t * btn;
+ btn = lv_win_add_btn(win, LV_SYMBOL_LEFT, 40);
+ lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
+
+ lv_win_add_title(win, "A title");
+
+ btn = lv_win_add_btn(win, LV_SYMBOL_RIGHT, 40);
+ lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
+
+ btn = lv_win_add_btn(win, LV_SYMBOL_CLOSE, 60);
+ lv_obj_add_event_cb(btn, event_handler, LV_EVENT_CLICKED, NULL);
+
+ lv_obj_t * cont = lv_win_get_content(win); /*Content can be added here*/
+ lv_obj_t * label = lv_label_create(cont);
+ lv_label_set_text(label, "This is\n"
+ "a pretty\n"
+ "long text\n"
+ "to see how\n"
+ "the window\n"
+ "becomes\n"
+ "scrollable.\n"
+ "\n"
+ "\n"
+ "Some more\n"
+ "text to be\n"
+ "sure it\n"
+ "overflows. :)");
+
+
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/win/lv_example_win_1.py b/lib/lvgl/examples/widgets/win/lv_example_win_1.py
new file mode 100644
index 00000000..2f5156ce
--- /dev/null
+++ b/lib/lvgl/examples/widgets/win/lv_example_win_1.py
@@ -0,0 +1,36 @@
+def event_handler(e):
+ code = e.get_code()
+ obj = e.get_target()
+ if code == lv.EVENT.CLICKED:
+ print("Button {:d} clicked".format(obj.get_child_id()))
+
+
+win = lv.win(lv.scr_act(), 60)
+btn1 = win.add_btn(lv.SYMBOL.LEFT, 40)
+btn1.add_event_cb(event_handler, lv.EVENT.ALL, None)
+win.add_title("A title")
+btn2=win.add_btn(lv.SYMBOL.RIGHT, 40)
+btn2.add_event_cb(event_handler, lv.EVENT.ALL, None)
+btn3 = win.add_btn(lv.SYMBOL.CLOSE, 60)
+btn3.add_event_cb(event_handler, lv.EVENT.ALL, None)
+
+cont = win.get_content() # Content can be added here
+label = lv.label(cont)
+label.set_text("""This is
+a pretty
+long text
+to see how
+the window
+becomes
+scrollable.
+
+
+We need
+quite some text
+and we will
+even put
+some more
+text to be
+sure it
+overflows.
+""")