一、前言
这里将介绍一系列控件,了解后就可以开始基础的开发了。
二、示例
1、Base Obj(基础对象)
1.1、示例1
#include "../../lv_examples.h"
#if LV_BUILD_EXAMPLESvoid lv_example_obj_1(void)
{lv_obj_t * obj1;obj1 = lv_obj_create(lv_screen_active());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_screen_active());lv_obj_add_style(obj2, &style_shadow, 0);lv_obj_align(obj2, LV_ALIGN_CENTER, 60, 30);
}
#endif
1.2、示例2
#include "../../lv_examples.h"
#if LV_BUILD_EXAMPLESstatic void drag_event_handler(lv_event_t * e)
{lv_obj_t * obj = lv_event_get_target(e);lv_indev_t * indev = lv_indev_active();if(indev == NULL) return;lv_point_t vect;lv_indev_get_vect(indev, &vect);int32_t x = lv_obj_get_x_aligned(obj) + vect.x;int32_t y = lv_obj_get_y_aligned(obj) + vect.y;lv_obj_set_pos(obj, x, y);
}/*** Make an object draggable.*/
void lv_example_obj_2(void)
{lv_obj_t * obj;obj = lv_obj_create(lv_screen_active());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
2、Arc(圆弧)
2.1、示例1
#include "../../lv_examples.h"#if LV_USE_ARC && LV_BUILD_EXAMPLESstatic void value_changed_event_cb(lv_event_t * e);void lv_example_arc_1(void)
{lv_obj_t * label = lv_label_create(lv_screen_active());/*Create an Arc*/lv_obj_t * arc = lv_arc_create(lv_screen_active());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_obj_send_event(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, "%" LV_PRId32 "%%", 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
2.2、示例2
#include "../../lv_examples.h"#if LV_USE_ARC && LV_BUILD_EXAMPLESstatic 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_screen_active());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_remove_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_duration(&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
3、bar(进度条)
3.1、示例1
#include "../../lv_examples.h"
#if LV_USE_BAR && LV_BUILD_EXAMPLESvoid lv_example_bar_1(void)
{lv_obj_t * bar1 = lv_bar_create(lv_screen_active());lv_obj_set_size(bar1, 200, 20);lv_obj_center(bar1);lv_bar_set_value(bar1, 70, LV_ANIM_OFF);
}#endif
3.2、示例2
#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_duration(&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_screen_active());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
3.3、示例3
#include "../../lv_examples.h"
#if LV_USE_BAR && LV_BUILD_EXAMPLESstatic 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_screen_active());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_duration(&a, 3000);lv_anim_set_playback_duration(&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
3.4、示例4
#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_IMAGE_DECLARE(img_skew_strip);static lv_style_t style_indic;lv_style_init(&style_indic);lv_style_set_bg_image_src(&style_indic, &img_skew_strip);lv_style_set_bg_image_tiled(&style_indic, true);lv_style_set_bg_image_opa(&style_indic, LV_OPA_30);lv_obj_t * bar = lv_bar_create(lv_screen_active());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
4.5、示例5
#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_screen_active());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_screen_active());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_screen_active());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_screen_active());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
4.6、示例6
#include "../../lv_examples.h"
#if LV_USE_BAR && LV_BUILD_EXAMPLESstatic 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_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_text_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;txt_area.x1 = 0;txt_area.x2 = txt_size.x - 1;txt_area.y1 = 0;txt_area.y2 = txt_size.y - 1;lv_bar_t * bar = (lv_bar_t *) obj;const lv_area_t * indic_area = &bar->indic_area;/*If the indicator is long enough put the text inside on the right*/if(lv_area_get_width(indic_area) > txt_size.x + 20) {lv_area_align(indic_area, &txt_area, LV_ALIGN_RIGHT_MID, -10, 0);label_dsc.color = lv_color_white();}/*If the indicator is still short put the text out of it on the right*/else {lv_area_align(indic_area, &txt_area, LV_ALIGN_OUT_RIGHT_MID, 10, 0);label_dsc.color = lv_color_black();}label_dsc.text = buf;label_dsc.text_local = true;lv_layer_t * layer = lv_event_get_layer(e);lv_draw_label(layer, &label_dsc, &txt_area);
}/*** Custom drawer on the bar to display the current value*/
void lv_example_bar_6(void)
{lv_obj_t * bar = lv_bar_create(lv_screen_active());lv_obj_set_size(bar, 200, 20);lv_obj_center(bar);lv_obj_add_event_cb(bar, event_cb, LV_EVENT_DRAW_MAIN_END, NULL);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_duration(&a, 4000);lv_anim_set_playback_duration(&a, 4000);lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);lv_anim_start(&a);}#endif
4.7、示例7
#include "../../lv_examples.h"
#if LV_USE_BAR && LV_BUILD_EXAMPLES/*** Bar with opposite direction*/
void lv_example_bar_7(void)
{lv_obj_t * label;lv_obj_t * bar_tob = lv_bar_create(lv_screen_active());lv_obj_set_size(bar_tob, 20, 200);lv_bar_set_range(bar_tob, 100, 0);lv_bar_set_value(bar_tob, 70, LV_ANIM_OFF);lv_obj_align(bar_tob, LV_ALIGN_CENTER, 0, -30);label = lv_label_create(lv_screen_active());lv_label_set_text(label, "From top to bottom");lv_obj_align_to(label, bar_tob, LV_ALIGN_OUT_TOP_MID, 0, -5);
}#endif
4、button(按钮)略
按钮在最开始的三大控件那里已经介绍过了。
5、button matrix(矩阵按钮)
5.1、示例1
#include "../../lv_examples.h"
#if LV_USE_BUTTONMATRIX && LV_BUILD_EXAMPLESstatic 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_buttonmatrix_get_selected_button(obj);const char * txt = lv_buttonmatrix_get_button_text(obj, id);LV_UNUSED(txt);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_buttonmatrix_1(void)
{lv_obj_t * btnm1 = lv_buttonmatrix_create(lv_screen_active());lv_buttonmatrix_set_map(btnm1, btnm_map);lv_buttonmatrix_set_button_width(btnm1, 10, 2); /*Make "Action1" twice as wide as "Action2"*/lv_buttonmatrix_set_button_ctrl(btnm1, 10, LV_BUTTONMATRIX_CTRL_CHECKABLE);lv_buttonmatrix_set_button_ctrl(btnm1, 11, LV_BUTTONMATRIX_CTRL_CHECKED);lv_obj_align(btnm1, LV_ALIGN_CENTER, 0, 0);lv_obj_add_event_cb(btnm1, event_handler, LV_EVENT_ALL, NULL);
}#endif
5.2、示例2
#include "../../lv_examples.h"
#if LV_USE_BUTTONMATRIX && LV_BUILD_EXAMPLESstatic void event_cb(lv_event_t * e)
{lv_obj_t * obj = lv_event_get_target(e);lv_draw_task_t * draw_task = lv_event_get_draw_task(e);lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;/*When the button matrix draws the buttons...*/if(base_dsc->part == LV_PART_ITEMS) {bool pressed = false;if(lv_buttonmatrix_get_selected_button(obj) == base_dsc->id1 && lv_obj_has_state(obj, LV_STATE_PRESSED)) {pressed = true;}/*Change the draw descriptor of the 2nd button*/if(base_dsc->id1 == 1) {lv_draw_fill_dsc_t * fill_draw_dsc = lv_draw_task_get_fill_dsc(draw_task);if(fill_draw_dsc) {fill_draw_dsc->radius = 0;if(pressed) fill_draw_dsc->color = lv_palette_darken(LV_PALETTE_BLUE, 3);else fill_draw_dsc->color = lv_palette_main(LV_PALETTE_BLUE);}lv_draw_box_shadow_dsc_t * box_shadow_draw_dsc = lv_draw_task_get_box_shadow_dsc(draw_task);if(box_shadow_draw_dsc) {box_shadow_draw_dsc->width = 6;box_shadow_draw_dsc->ofs_x = 3;box_shadow_draw_dsc->ofs_y = 3;}lv_draw_label_dsc_t * label_draw_dsc = lv_draw_task_get_label_dsc(draw_task);if(label_draw_dsc) {label_draw_dsc->color = lv_color_white();}}/*Change the draw descriptor of the 3rd button*/else if(base_dsc->id1 == 2) {lv_draw_fill_dsc_t * fill_draw_dsc = lv_draw_task_get_fill_dsc(draw_task);if(fill_draw_dsc) {fill_draw_dsc->radius = LV_RADIUS_CIRCLE;if(pressed) fill_draw_dsc->color = lv_palette_darken(LV_PALETTE_RED, 3);else fill_draw_dsc->color = lv_palette_main(LV_PALETTE_RED);}}else if(base_dsc->id1 == 3) {lv_draw_label_dsc_t * label_draw_dsc = lv_draw_task_get_label_dsc(draw_task);if(label_draw_dsc) {label_draw_dsc->opa = 0;}if(draw_task->type == LV_DRAW_TASK_TYPE_FILL) {LV_IMAGE_DECLARE(img_star);lv_image_header_t header;lv_result_t res = lv_image_decoder_get_info(&img_star, &header);if(res != LV_RESULT_OK) return;lv_area_t a;a.x1 = 0;a.x2 = header.w - 1;a.y1 = 0;a.y2 = header.h - 1;lv_area_align(&draw_task->area, &a, LV_ALIGN_CENTER, 0, 0);lv_draw_image_dsc_t img_draw_dsc;lv_draw_image_dsc_init(&img_draw_dsc);img_draw_dsc.src = &img_star;img_draw_dsc.recolor = lv_color_black();if(pressed) img_draw_dsc.recolor_opa = LV_OPA_30;lv_draw_image(base_dsc->layer, &img_draw_dsc, &a);}}}
}/*** Add custom drawer to the button matrix to customize buttons one by one*/
void lv_example_buttonmatrix_2(void)
{lv_obj_t * btnm = lv_buttonmatrix_create(lv_screen_active());lv_obj_add_event_cb(btnm, event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);lv_obj_add_flag(btnm, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);lv_obj_center(btnm);
}#endif
5.3、示例3
#include "../../lv_examples.h"
#if LV_USE_BUTTONMATRIX && LV_BUILD_EXAMPLESstatic void event_cb(lv_event_t * e)
{lv_obj_t * obj = lv_event_get_target(e);uint32_t id = lv_buttonmatrix_get_selected_button(obj);bool prev = id == 0;bool next = id == 6;if(prev || next) {/*Find the checked button*/uint32_t i;for(i = 1; i < 7; i++) {if(lv_buttonmatrix_has_button_ctrl(obj, i, LV_BUTTONMATRIX_CTRL_CHECKED)) break;}if(prev && i > 1) i--;else if(next && i < 5) i++;lv_buttonmatrix_set_button_ctrl(obj, i, LV_BUTTONMATRIX_CTRL_CHECKED);}
}/*** Make a button group (pagination)*/
void lv_example_buttonmatrix_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_buttonmatrix_create(lv_screen_active());lv_buttonmatrix_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_buttonmatrix_set_button_ctrl_all(btnm, LV_BUTTONMATRIX_CTRL_CHECKABLE);lv_buttonmatrix_clear_button_ctrl(btnm, 0, LV_BUTTONMATRIX_CTRL_CHECKABLE);lv_buttonmatrix_clear_button_ctrl(btnm, 6, LV_BUTTONMATRIX_CTRL_CHECKABLE);lv_buttonmatrix_set_one_checked(btnm, true);lv_buttonmatrix_set_button_ctrl(btnm, 1, LV_BUTTONMATRIX_CTRL_CHECKED);lv_obj_center(btnm);}#endif
6、Calendar(日历)
#include "../../lv_examples.h"
#if LV_USE_CALENDAR && LV_BUILD_EXAMPLESstatic 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_screen_active());lv_obj_set_size(calendar, 185, 230);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_DROPDOWNlv_calendar_header_dropdown_create(calendar);
#elif LV_USE_CALENDAR_HEADER_ARROWlv_calendar_header_arrow_create(calendar);
#endif
}#endif
7、Canvas(画布)
7.1、示例1
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES#define CANVAS_WIDTH 200
#define CANVAS_HEIGHT 150void 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_VER;rect_dsc.bg_grad.stops[0].color = lv_palette_main(LV_PALETTE_RED);rect_dsc.bg_grad.stops[0].opa = LV_OPA_100;rect_dsc.bg_grad.stops[1].color = lv_palette_main(LV_PALETTE_BLUE);rect_dsc.bg_grad.stops[1].opa = LV_OPA_50;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_offset_x = 5;rect_dsc.shadow_offset_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);label_dsc.text = "Some text on text canvas";/*Create a buffer for the canvas*/LV_DRAW_BUF_DEFINE(draw_buf_16bpp, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_RGB565);lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf_16bpp);lv_obj_center(canvas);lv_canvas_fill_bg(canvas, lv_palette_lighten(LV_PALETTE_GREY, 3), LV_OPA_COVER);lv_layer_t layer;lv_canvas_init_layer(canvas, &layer);lv_area_t coords_rect = {30, 20, 100, 70};lv_draw_rect(&layer, &rect_dsc, &coords_rect);lv_area_t coords_text = {40, 80, 100, 120};lv_draw_label(&layer, &label_dsc, &coords_text);lv_canvas_finish_layer(canvas, &layer);/*Test the rotation. It requires another buffer where the original image is stored.*So use previous canvas as image and rotate it to the new canvas*/LV_DRAW_BUF_DEFINE(draw_buf_32bpp, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);/*Create a canvas and initialize its palette*/canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf_32bpp);lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);lv_obj_center(canvas);lv_canvas_fill_bg(canvas, lv_palette_lighten(LV_PALETTE_GREY, 1), LV_OPA_COVER);lv_canvas_init_layer(canvas, &layer);lv_image_dsc_t img;lv_draw_buf_to_image(&draw_buf_16bpp, &img);lv_draw_image_dsc_t img_dsc;lv_draw_image_dsc_init(&img_dsc);img_dsc.rotation = 120;img_dsc.src = &img;img_dsc.pivot.x = CANVAS_WIDTH / 2;img_dsc.pivot.y = CANVAS_HEIGHT / 2;lv_area_t coords_img = {0, 0, CANVAS_WIDTH - 1, CANVAS_HEIGHT - 1};lv_draw_image(&layer, &img_dsc, &coords_img);lv_canvas_finish_layer(canvas, &layer);
}#endif
7.2、示例2
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES#define CANVAS_WIDTH 80
#define CANVAS_HEIGHT 40/*** Create a transparent canvas with transparency*/
void lv_example_canvas_2(void)
{lv_obj_set_style_bg_color(lv_screen_active(), lv_palette_lighten(LV_PALETTE_RED, 5), 0);/*Create a buffer for the canvas*/LV_DRAW_BUF_DEFINE(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);/*Create a canvas and initialize its palette*/lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf);lv_obj_center(canvas);/*Red background (There is no dedicated alpha channel in indexed images so LV_OPA_COVER is ignored)*/lv_canvas_fill_bg(canvas, lv_palette_main(LV_PALETTE_BLUE), LV_OPA_COVER);/*Create hole on the canvas*/uint32_t x;uint32_t y;for(y = 10; y < 20; y++) {for(x = 5; x < 75; x++) {lv_canvas_set_px(canvas, x, y, lv_palette_main(LV_PALETTE_BLUE), LV_OPA_50);}}for(y = 20; y < 30; y++) {for(x = 5; x < 75; x++) {lv_canvas_set_px(canvas, x, y, lv_palette_main(LV_PALETTE_BLUE), LV_OPA_20);}}for(y = 30; y < 40; y++) {for(x = 5; x < 75; x++) {lv_canvas_set_px(canvas, x, y, lv_palette_main(LV_PALETTE_BLUE), LV_OPA_0);}}
}
#endif
7.3、示例3
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES#define CANVAS_WIDTH 50
#define CANVAS_HEIGHT 50/*** Draw a rectangle to the canvas*/
void lv_example_canvas_3(void)
{/*Create a buffer for the canvas*/LV_DRAW_BUF_DEFINE(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);/*Create a canvas and initialize its palette*/lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf);lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);lv_obj_center(canvas);lv_layer_t layer;lv_canvas_init_layer(canvas, &layer);lv_draw_rect_dsc_t dsc;lv_draw_rect_dsc_init(&dsc);dsc.bg_color = lv_palette_main(LV_PALETTE_RED);dsc.border_color = lv_palette_main(LV_PALETTE_BLUE);dsc.border_width = 3;dsc.outline_color = lv_palette_main(LV_PALETTE_GREEN);dsc.outline_width = 2;dsc.outline_pad = 2;dsc.outline_opa = LV_OPA_50;dsc.radius = 5;dsc.border_width = 3;lv_area_t coords = {10, 10, 40, 30};lv_draw_rect(&layer, &dsc, &coords);lv_canvas_finish_layer(canvas, &layer);
}
#endif
7.4、示例4
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_FONT_MONTSERRAT_14 && LV_BUILD_EXAMPLES#define CANVAS_WIDTH 50
#define CANVAS_HEIGHT 50/*** Draw a text to the canvas*/
void lv_example_canvas_4(void)
{/*Create a buffer for the canvas*/LV_DRAW_BUF_DEFINE(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);/*Create a canvas and initialize its palette*/lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf);lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);lv_obj_center(canvas);lv_layer_t layer;lv_canvas_init_layer(canvas, &layer);lv_draw_label_dsc_t dsc;lv_draw_label_dsc_init(&dsc);dsc.color = lv_palette_main(LV_PALETTE_RED);dsc.font = &lv_font_montserrat_14;dsc.decor = LV_TEXT_DECOR_UNDERLINE;dsc.text = "Hello";lv_area_t coords = {10, 10, 30, 60};lv_draw_label(&layer, &dsc, &coords);lv_canvas_finish_layer(canvas, &layer);}
#endif
这里把原来的LV_FONT_MONTSERRAT_18改成LV_FONT_MONTSERRAT_14,lv_font_montserrat_18也改成lv_font_montserrat_14。
模拟环境一些依赖库没有。
7.5、示例5
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES#define CANVAS_WIDTH 50
#define CANVAS_HEIGHT 50/*** Draw an arc to the canvas*/
void lv_example_canvas_5(void)
{/*Create a buffer for the canvas*/LV_DRAW_BUF_DEFINE(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);/*Create a canvas and initialize its palette*/lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf);lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);lv_obj_center(canvas);lv_layer_t layer;lv_canvas_init_layer(canvas, &layer);lv_draw_arc_dsc_t dsc;lv_draw_arc_dsc_init(&dsc);dsc.color = lv_palette_main(LV_PALETTE_RED);dsc.width = 5;dsc.center.x = 25;dsc.center.y = 25;dsc.width = 10;dsc.radius = 15;dsc.start_angle = 0;dsc.end_angle = 220;lv_draw_arc(&layer, &dsc);lv_canvas_finish_layer(canvas, &layer);}
#endif
7.6、示例6
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES#define CANVAS_WIDTH 50
#define CANVAS_HEIGHT 50/*** Draw an image to the canvas*/
void lv_example_canvas_6(void)
{/*Create a buffer for the canvas*/static uint8_t cbuf[LV_CANVAS_BUF_SIZE(CANVAS_WIDTH, CANVAS_HEIGHT, 32, LV_DRAW_BUF_STRIDE_ALIGN)];/*Create a canvas and initialize its palette*/lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_buffer(canvas, cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);lv_obj_center(canvas);lv_layer_t layer;lv_canvas_init_layer(canvas, &layer);LV_IMAGE_DECLARE(img_star);lv_draw_image_dsc_t dsc;lv_draw_image_dsc_init(&dsc);dsc.src = &img_star;lv_area_t coords = {10, 10, 10 + img_star.header.w - 1, 10 + img_star.header.h - 1};lv_draw_image(&layer, &dsc, &coords);
}
#endif
7.7、示例7
#include "../../lv_examples.h"
#if LV_USE_CANVAS&& LV_BUILD_EXAMPLES#define CANVAS_WIDTH 50
#define CANVAS_HEIGHT 50/*** Draw a line to the canvas*/
void lv_example_canvas_7(void)
{/*Create a buffer for the canvas*/LV_DRAW_BUF_DEFINE(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);/*Create a canvas and initialize its palette*/lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf);lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);lv_obj_center(canvas);lv_layer_t layer;lv_canvas_init_layer(canvas, &layer);lv_draw_line_dsc_t dsc;lv_draw_line_dsc_init(&dsc);dsc.color = lv_palette_main(LV_PALETTE_RED);dsc.width = 4;dsc.round_end = 1;dsc.round_start = 1;dsc.p1.x = 15;dsc.p1.y = 15;dsc.p2.x = 35;dsc.p2.y = 10;lv_draw_line(&layer, &dsc);lv_canvas_finish_layer(canvas, &layer);}
#endif
7.8、示例8
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES#if LV_USE_VECTOR_GRAPHIC#define CANVAS_WIDTH 150
#define CANVAS_HEIGHT 150/*** Draw a path to the canvas*/
void lv_example_canvas_8(void)
{/*Create a buffer for the canvas*/LV_DRAW_BUF_DEFINE(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);/*Create a canvas and initialize its palette*/lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf);lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);lv_obj_center(canvas);lv_layer_t layer;lv_canvas_init_layer(canvas, &layer);lv_vector_dsc_t * dsc = lv_vector_dsc_create(&layer);lv_vector_path_t * path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM);lv_fpoint_t pts[] = {{10, 10}, {130, 130}, {10, 130}};lv_vector_path_move_to(path, &pts[0]);lv_vector_path_line_to(path, &pts[1]);lv_vector_path_line_to(path, &pts[2]);lv_vector_path_close(path);lv_vector_dsc_set_fill_color(dsc, lv_color_make(0x00, 0x80, 0xff));lv_vector_dsc_add_path(dsc, path);lv_draw_vector(dsc);lv_vector_path_delete(path);lv_vector_dsc_delete(dsc);lv_canvas_finish_layer(canvas, &layer);
}
#elsevoid lv_example_canvas_8(void)
{/*fallback for online examples*/lv_obj_t * label = lv_label_create(lv_screen_active());lv_label_set_text(label, "Vector graphics is not enabled");lv_obj_center(label);
}#endif /*LV_USE_VECTOR_GRAPHIC*/#endif
可以在lv_conf.h中开启对应扩展:
#define LV_USE_VECTOR_GRAPHIC 1
不开启矢量图扩展会提示:
8、chart(图表)
8.1、示例1
#include "../../lv_examples.h"
#if LV_USE_CHART && LV_BUILD_EXAMPLES/*** A very basic line chart*/
void lv_example_chart_1(void)
{/*Create a chart*/lv_obj_t * chart;chart = lv_chart_create(lv_screen_active());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_GREEN), LV_CHART_AXIS_PRIMARY_Y);lv_chart_series_t * ser2 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_SECONDARY_Y);uint32_t i;for(i = 0; i < 10; i++) {/*Set the next points on 'ser1'*/lv_chart_set_next_value(chart, ser1, lv_rand(10, 50));/*Directly set points on 'ser2'*/ser2->y_points[i] = lv_rand(50, 90);}lv_chart_refresh(chart); /*Required after direct set*/
}#endif
8.2、示例2
#include "../../lv_examples.h"
#if LV_USE_CHART && LV_BUILD_EXAMPLES/*** Use lv_scale to add ticks to a scrollable chart*/
void lv_example_chart_2(void)
{/*Create a container*/lv_obj_t * main_cont = lv_obj_create(lv_screen_active());lv_obj_set_size(main_cont, 200, 150);lv_obj_center(main_cont);/*Create a transparent wrapper for the chart and the scale.*Set a large width, to make it scrollable on the main container*/lv_obj_t * wrapper = lv_obj_create(main_cont);lv_obj_remove_style_all(wrapper);lv_obj_set_size(wrapper, lv_pct(300), lv_pct(100));lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN);/*Create a chart on the wrapper*Set it's width to 100% to fill the large wrapper*/lv_obj_t * chart = lv_chart_create(wrapper);lv_obj_set_width(chart, lv_pct(100));lv_obj_set_flex_grow(chart, 1);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_set_style_radius(chart, 0, 0);/*Create a scale also with 100% width*/lv_obj_t * scale_bottom = lv_scale_create(wrapper);lv_scale_set_mode(scale_bottom, LV_SCALE_MODE_HORIZONTAL_BOTTOM);lv_obj_set_size(scale_bottom, lv_pct(100), 25);lv_scale_set_total_tick_count(scale_bottom, 12);lv_scale_set_major_tick_every(scale_bottom, 1);lv_obj_set_style_pad_hor(scale_bottom, lv_chart_get_first_point_center_offset(chart), 0);static const char * month[] = {"Jan", "Febr", "March", "Apr", "May", "Jun", "July", "Aug", "Sept", "Oct", "Nov", "Dec", NULL};lv_scale_set_text_src(scale_bottom, month);/*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_PRIMARY_Y);/*Set the next points on 'ser1'*/uint32_t i;for(i = 0; i < 12; i++) {lv_chart_set_next_value(chart, ser1, lv_rand(10, 60));lv_chart_set_next_value(chart, ser2, lv_rand(50, 90));}lv_chart_refresh(chart); /*Required after direct set*/
}#endif
8.3、示例3
#include "../../lv_examples.h"
#if LV_USE_CHART && LV_BUILD_EXAMPLESstatic 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) {int32_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);int32_t * y_array = lv_chart_get_y_array(chart, ser);int32_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_image_src = buf;draw_rect_dsc.bg_image_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_layer_t * layer = lv_event_get_layer(e);lv_draw_rect(layer, &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_3(void)
{/*Create a chart*/lv_obj_t * chart;chart = lv_chart_create(lv_screen_active());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_scale_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
8.4、示例4
#include "../../lv_examples.h"#if LV_USE_CHART && LV_DRAW_SW_COMPLEX && LV_BUILD_EXAMPLESstatic void draw_event_cb(lv_event_t * e)
{lv_draw_task_t * draw_task = lv_event_get_draw_task(e);lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;if(base_dsc->part != LV_PART_ITEMS) {return;}lv_draw_fill_dsc_t * fill_dsc = lv_draw_task_get_fill_dsc(draw_task);if(fill_dsc) {lv_obj_t * chart = lv_event_get_target(e);int32_t * y_array = lv_chart_get_y_array(chart, lv_chart_get_series_next(chart, NULL));int32_t v = y_array[base_dsc->id2];uint32_t ratio = v * 255 / 100;fill_dsc->color = lv_color_mix(lv_palette_main(LV_PALETTE_GREEN), lv_palette_main(LV_PALETTE_RED), ratio);}
}/*** Recolor the bars of a chart based on their value*/
void lv_example_chart_4(void)
{/*Create a chart1*/lv_obj_t * chart = lv_chart_create(lv_screen_active());lv_chart_set_type(chart, LV_CHART_TYPE_BAR);lv_chart_set_point_count(chart, 24);lv_obj_set_style_pad_column(chart, 2, 0);lv_obj_set_size(chart, 260, 160);lv_obj_center(chart);lv_chart_series_t * ser = lv_chart_add_series(chart, lv_color_hex(0xff0000), LV_CHART_AXIS_PRIMARY_Y);lv_obj_add_event_cb(chart, draw_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);lv_obj_add_flag(chart, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);uint32_t i;for(i = 0; i < 24; i++) {lv_chart_set_next_value(chart, ser, lv_rand(10, 90));}
}#endif
8.5、示例5
#include "../../lv_examples.h"#if LV_USE_CHART && LV_DRAW_SW_COMPLEX && LV_BUILD_EXAMPLESstatic void hook_division_lines(lv_event_t * e);
static void add_faded_area(lv_event_t * e);
static void draw_event_cb(lv_event_t * e);/*** Add a faded area effect to the line chart and make some division lines ticker*/
void lv_example_chart_5(void)
{/*Create a chart*/lv_obj_t * chart = lv_chart_create(lv_screen_active());lv_chart_set_type(chart, LV_CHART_TYPE_LINE); /*Show lines and points too*/lv_obj_set_size(chart, 200, 150);lv_obj_set_style_pad_all(chart, 0, 0);lv_obj_set_style_radius(chart, 0, 0);lv_obj_center(chart);lv_chart_set_div_line_count(chart, 5, 7);lv_obj_add_event_cb(chart, draw_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);lv_obj_add_flag(chart, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);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 < 10; i++) {lv_chart_set_next_value(chart, ser, lv_rand(10, 80));}
}static void draw_event_cb(lv_event_t * e)
{lv_draw_task_t * draw_task = lv_event_get_draw_task(e);lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;if(base_dsc->part == LV_PART_ITEMS && draw_task->type == LV_DRAW_TASK_TYPE_LINE) {add_faded_area(e);}/*Hook the division lines too*/if(base_dsc->part == LV_PART_MAIN && draw_task->type == LV_DRAW_TASK_TYPE_LINE) {hook_division_lines(e);}
}static void add_faded_area(lv_event_t * e)
{lv_obj_t * obj = lv_event_get_target(e);lv_draw_task_t * draw_task = lv_event_get_draw_task(e);lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;const lv_chart_series_t * ser = lv_chart_get_series_next(obj, NULL);/*Draw a triangle below the line witch some opacity gradient*/lv_draw_line_dsc_t * draw_line_dsc = draw_task->draw_dsc;lv_draw_triangle_dsc_t tri_dsc;lv_draw_triangle_dsc_init(&tri_dsc);tri_dsc.p[0].x = draw_line_dsc->p1.x;tri_dsc.p[0].y = draw_line_dsc->p1.y;tri_dsc.p[1].x = draw_line_dsc->p2.x;tri_dsc.p[1].y = draw_line_dsc->p2.y;tri_dsc.p[2].x = draw_line_dsc->p1.y < draw_line_dsc->p2.y ? draw_line_dsc->p1.x : draw_line_dsc->p2.x;tri_dsc.p[2].y = LV_MAX(draw_line_dsc->p1.y, draw_line_dsc->p2.y);tri_dsc.bg_grad.dir = LV_GRAD_DIR_VER;int32_t full_h = lv_obj_get_height(obj);int32_t fract_uppter = (int32_t)(LV_MIN(draw_line_dsc->p1.y, draw_line_dsc->p2.y) - obj->coords.y1) * 255 / full_h;int32_t fract_lower = (int32_t)(LV_MAX(draw_line_dsc->p1.y, draw_line_dsc->p2.y) - obj->coords.y1) * 255 / full_h;tri_dsc.bg_grad.stops[0].color = ser->color;tri_dsc.bg_grad.stops[0].opa = 255 - fract_uppter;tri_dsc.bg_grad.stops[0].frac = 0;tri_dsc.bg_grad.stops[1].color = ser->color;tri_dsc.bg_grad.stops[1].opa = 255 - fract_lower;tri_dsc.bg_grad.stops[1].frac = 255;lv_draw_triangle(base_dsc->layer, &tri_dsc);/*Draw rectangle below the triangle*/lv_draw_rect_dsc_t rect_dsc;lv_draw_rect_dsc_init(&rect_dsc);rect_dsc.bg_grad.dir = LV_GRAD_DIR_VER;rect_dsc.bg_grad.stops[0].color = ser->color;rect_dsc.bg_grad.stops[0].frac = 0;rect_dsc.bg_grad.stops[0].opa = 255 - fract_lower;rect_dsc.bg_grad.stops[1].color = ser->color;rect_dsc.bg_grad.stops[1].frac = 255;rect_dsc.bg_grad.stops[1].opa = 0;lv_area_t rect_area;rect_area.x1 = (int32_t)draw_line_dsc->p1.x;rect_area.x2 = (int32_t)draw_line_dsc->p2.x - 1;rect_area.y1 = (int32_t)LV_MAX(draw_line_dsc->p1.y, draw_line_dsc->p2.y) - 1;rect_area.y2 = (int32_t)obj->coords.y2;lv_draw_rect(base_dsc->layer, &rect_dsc, &rect_area);
}static void hook_division_lines(lv_event_t * e)
{lv_draw_task_t * draw_task = lv_event_get_draw_task(e);lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;lv_draw_line_dsc_t * line_dsc = draw_task->draw_dsc;/*Vertical line*/if(line_dsc->p1.x == line_dsc->p2.x) {line_dsc->color = lv_palette_lighten(LV_PALETTE_GREY, 1);if(base_dsc->id1 == 3) {line_dsc->width = 2;line_dsc->dash_gap = 0;line_dsc->dash_width = 0;}else {line_dsc->width = 1;line_dsc->dash_gap = 6;line_dsc->dash_width = 6;}}/*Horizontal line*/else {if(base_dsc->id1 == 2) {line_dsc->width = 2;line_dsc->dash_gap = 0;line_dsc->dash_width = 0;}else {line_dsc->width = 2;line_dsc->dash_gap = 6;line_dsc->dash_width = 6;}if(base_dsc->id1 == 1 || base_dsc->id1 == 3) {line_dsc->color = lv_palette_main(LV_PALETTE_GREEN);}else {line_dsc->color = lv_palette_lighten(LV_PALETTE_GREY, 1);}}
}#endif
8.6、示例6
#include "../../lv_examples.h"
#if LV_USE_CHART && LV_BUILD_EXAMPLESstatic lv_obj_t * chart;
static lv_chart_series_t * ser;
static lv_chart_cursor_t * cursor;static void value_changed_event_cb(lv_event_t * e)
{static int32_t last_id = -1;lv_obj_t * obj = lv_event_get_target(e);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);}
}/*** Show cursor on the clicked point*/
void lv_example_chart_6(void)
{chart = lv_chart_create(lv_screen_active());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, value_changed_event_cb, LV_EVENT_VALUE_CHANGED, 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_scale_x(chart, 500);lv_obj_t * label = lv_label_create(lv_screen_active());lv_label_set_text(label, "Click on a point");lv_obj_align_to(label, chart, LV_ALIGN_OUT_TOP_MID, 0, -5);
}#endif
8.7、示例7
#include "../../lv_examples.h"
#if LV_USE_CHART && LV_BUILD_EXAMPLESstatic void draw_event_cb(lv_event_t * e)
{lv_draw_task_t * draw_task = lv_event_get_draw_task(e);lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;if(base_dsc->part == LV_PART_INDICATOR) {lv_obj_t * obj = lv_event_get_target(e);lv_chart_series_t * ser = lv_chart_get_series_next(obj, NULL);lv_draw_rect_dsc_t * rect_draw_dsc = draw_task->draw_dsc;uint32_t cnt = lv_chart_get_point_count(obj);/*Make older value more transparent*/rect_draw_dsc->bg_opa = (LV_OPA_COVER * base_dsc->id2) / (cnt - 1);/*Make smaller values blue, higher values red*/int32_t * x_array = lv_chart_get_x_array(obj, ser);int32_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 + base_dsc->id2) % 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;rect_draw_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_screen_active());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_TASK_ADDED, NULL);lv_obj_add_flag(chart, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);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_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
8.8、示例8
#include "../../lv_examples.h"
#if LV_USE_CHART && LV_DRAW_SW_COMPLEX && LV_BUILD_EXAMPLESstatic 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);int32_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_8(void)
{/*Create a stacked_area_chart.obj*/lv_obj_t * chart = lv_chart_create(lv_screen_active());lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_CIRCULAR);lv_obj_set_style_size(chart, 0, 0, LV_PART_INDICATOR);lv_obj_set_size(chart, 280, 150);lv_obj_center(chart);lv_chart_set_point_count(chart, 80);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 < 80; i++) {lv_chart_set_next_value(chart, ser, lv_rand(10, 90));}lv_timer_create(add_data, 300, chart);}#endif
9、checkbox(复选框)
9.1、示例1
#include "../../lv_examples.h"
#if LV_USE_CHECKBOX && LV_BUILD_EXAMPLESstatic 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_UNUSED(obj);const char * txt = lv_checkbox_get_text(obj);const char * state = lv_obj_get_state(obj) & LV_STATE_CHECKED ? "Checked" : "Unchecked";LV_UNUSED(txt);LV_UNUSED(state);LV_LOG_USER("%s: %s", txt, state);}
}void lv_example_checkbox_1(void)
{lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN);lv_obj_set_flex_align(lv_screen_active(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER);lv_obj_t * cb;cb = lv_checkbox_create(lv_screen_active());lv_checkbox_set_text(cb, "Apple");lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL);cb = lv_checkbox_create(lv_screen_active());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_screen_active());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_screen_active());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
9.2、示例2
#include "../../lv_examples.h"
#if LV_USE_CHECKBOX && LV_BUILD_EXAMPLESstatic 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_remove_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_image_src(&style_radio_chk, NULL);uint32_t i;char buf[32];lv_obj_t * cont1 = lv_obj_create(lv_screen_active());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_screen_active());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
10、dropdown(下拉列表)
10.1、示例1
#include "../../lv_examples.h"
#if LV_USE_DROPDOWN && LV_BUILD_EXAMPLESstatic 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_screen_active());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
10.2、示例2
#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_screen_active());lv_dropdown_set_options_static(dd, opts);lv_obj_align(dd, LV_ALIGN_TOP_MID, 0, 10);dd = lv_dropdown_create(lv_screen_active());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_screen_active());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_screen_active());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
10.3、示例3
#include "../../lv_examples.h"
#if LV_USE_DROPDOWN && LV_BUILD_EXAMPLESstatic 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_screen_active());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_IMAGE_DECLARE(img_caret_down);lv_dropdown_set_symbol(dropdown, &img_caret_down);lv_obj_set_style_transform_rotation(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
三、最后
接下来我们进行其他控件的总结,总共有三十类左右的控件,我们大体都过一遍,其他的UI开发其实都是可以触类旁通的。