arch(draw): add parallel rendering architecture
BREAKING CHANGE This is a huge update which introduces parallel rendering. lv_conf.h needs to be updated too.
This commit is contained in:
@@ -8,9 +8,6 @@ static void set_value(void * bar, int32_t v)
|
||||
|
||||
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;
|
||||
@@ -25,23 +22,28 @@ static void event_cb(lv_event_t * e)
|
||||
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(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;
|
||||
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 {
|
||||
txt_area.x1 = dsc->draw_area->x2 + 5;
|
||||
txt_area.x2 = txt_area.x1 + txt_size.x - 1;
|
||||
lv_area_align(indic_area, &txt_area, LV_ALIGN_OUT_RIGHT_MID, 10, 0);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,17 +52,17 @@ static void event_cb(lv_event_t * e)
|
||||
void lv_example_bar_6(void)
|
||||
{
|
||||
lv_obj_t * bar = lv_bar_create(lv_scr_act());
|
||||
lv_obj_add_event(bar, event_cb, LV_EVENT_DRAW_PART_END, NULL);
|
||||
lv_obj_set_size(bar, 200, 20);
|
||||
lv_obj_center(bar);
|
||||
lv_obj_add_event(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_time(&a, 2000);
|
||||
lv_anim_set_playback_time(&a, 2000);
|
||||
lv_anim_set_time(&a, 4000);
|
||||
lv_anim_set_playback_time(&a, 4000);
|
||||
lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
|
||||
lv_anim_start(&a);
|
||||
|
||||
|
||||
@@ -1,54 +1 @@
|
||||
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_obj()
|
||||
|
||||
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(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)
|
||||
|
||||
pass
|
||||
|
||||
@@ -20,6 +20,10 @@ void lv_example_btn_1(void)
|
||||
lv_obj_t * btn1 = lv_btn_create(lv_scr_act());
|
||||
lv_obj_add_event(btn1, event_handler, LV_EVENT_ALL, NULL);
|
||||
lv_obj_align(btn1, LV_ALIGN_CENTER, 0, -40);
|
||||
lv_obj_set_size(btn1, 182, 105);
|
||||
lv_obj_set_style_transform_angle(btn1, 300, 0);
|
||||
lv_obj_set_style_radius(btn1, 0, 0);
|
||||
lv_obj_set_style_shadow_width(btn1, 0, 0);
|
||||
|
||||
label = lv_label_create(btn1);
|
||||
lv_label_set_text(label, "Button");
|
||||
@@ -34,5 +38,6 @@ void lv_example_btn_1(void)
|
||||
label = lv_label_create(btn2);
|
||||
lv_label_set_text(label, "Toggle");
|
||||
lv_obj_center(label);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4,62 +4,68 @@
|
||||
|
||||
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);
|
||||
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_btnmatrix_get_selected_btn(obj) == base_dsc->id1 && lv_obj_has_state(obj, LV_STATE_PRESSED)) {
|
||||
pressed = true;
|
||||
}
|
||||
|
||||
/*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 2nd button*/
|
||||
if(base_dsc->id1 == 1) {
|
||||
if(draw_task->type == LV_DRAW_TASK_TYPE_FILL) {
|
||||
lv_draw_rect_dsc_t * rect_draw_dsc = draw_task->draw_dsc;
|
||||
rect_draw_dsc->radius = 0;
|
||||
if(pressed) rect_draw_dsc->bg_color = lv_palette_darken(LV_PALETTE_BLUE, 3);
|
||||
else rect_draw_dsc->bg_color = lv_palette_main(LV_PALETTE_BLUE);
|
||||
rect_draw_dsc->shadow_width = 6;
|
||||
rect_draw_dsc->shadow_ofs_x = 3;
|
||||
rect_draw_dsc->shadow_ofs_y = 3;
|
||||
}
|
||||
/*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();
|
||||
if(draw_task->type == LV_DRAW_TASK_TYPE_LABEL) {
|
||||
lv_draw_label_dsc_t * label_draw_dsc = draw_task->draw_dsc;
|
||||
label_draw_dsc->color = lv_color_white();
|
||||
}
|
||||
else if(dsc->id == 3) {
|
||||
dsc->label_dsc->opa = LV_OPA_TRANSP; /*Hide the text if any*/
|
||||
|
||||
}
|
||||
/*Change the draw descriptor of the 3rd button*/
|
||||
else if(base_dsc->id1 == 2) {
|
||||
if(draw_task->type == LV_DRAW_TASK_TYPE_FILL) {
|
||||
lv_draw_rect_dsc_t * rect_draw_dsc = draw_task->draw_dsc;
|
||||
rect_draw_dsc->radius = LV_RADIUS_CIRCLE;
|
||||
if(pressed) rect_draw_dsc->bg_color = lv_palette_darken(LV_PALETTE_RED, 3);
|
||||
else rect_draw_dsc->bg_color = lv_palette_main(LV_PALETTE_RED);
|
||||
}
|
||||
}
|
||||
}
|
||||
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) {
|
||||
else if(base_dsc->id1 == 3) {
|
||||
if(draw_task->type == LV_DRAW_TASK_TYPE_LABEL) {
|
||||
lv_draw_label_dsc_t * label_draw_dsc = draw_task->draw_dsc;
|
||||
label_draw_dsc->opa = 0;
|
||||
}
|
||||
if(draw_task->type == LV_DRAW_TASK_TYPE_FILL) {
|
||||
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;
|
||||
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_img_dsc_t img_draw_dsc;
|
||||
lv_draw_img_dsc_init(&img_draw_dsc);
|
||||
img_draw_dsc.src = &img_star;
|
||||
img_draw_dsc.recolor = lv_color_black();
|
||||
if(lv_btnmatrix_get_selected_btn(obj) == dsc->id) img_draw_dsc.recolor_opa = LV_OPA_30;
|
||||
if(pressed) img_draw_dsc.recolor_opa = LV_OPA_30;
|
||||
|
||||
lv_draw_img(base_dsc->layer, &img_draw_dsc, &a);
|
||||
|
||||
lv_draw_img(dsc->draw_ctx, &img_draw_dsc, &a, &img_star);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,7 +77,8 @@ static void event_cb(lv_event_t * e)
|
||||
void lv_example_btnmatrix_2(void)
|
||||
{
|
||||
lv_obj_t * btnm = lv_btnmatrix_create(lv_scr_act());
|
||||
lv_obj_add_event(btnm, event_cb, LV_EVENT_ALL, NULL);
|
||||
lv_obj_add_event(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);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
# 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_obj()
|
||||
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(event_cb, lv.EVENT.ALL, None)
|
||||
btnm.center()
|
||||
|
||||
|
||||
@@ -11,9 +11,11 @@ void lv_example_canvas_1(void)
|
||||
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.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();
|
||||
@@ -24,6 +26,7 @@ void lv_example_canvas_1(void)
|
||||
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";
|
||||
|
||||
static uint8_t cbuf[LV_CANVAS_BUF_SIZE_TRUE_COLOR(CANVAS_WIDTH, CANVAS_HEIGHT)];
|
||||
|
||||
@@ -32,22 +35,44 @@ void lv_example_canvas_1(void)
|
||||
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");
|
||||
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 copy the current image to buffer and rotate it to the canvas*/
|
||||
static uint8_t cbuf_tmp[LV_CANVAS_BUF_SIZE_TRUE_COLOR(CANVAS_WIDTH, CANVAS_HEIGHT)];
|
||||
memcpy(cbuf_tmp, cbuf, sizeof(cbuf_tmp));
|
||||
lv_memcpy(cbuf_tmp, cbuf, sizeof(cbuf_tmp));
|
||||
lv_img_dsc_t img;
|
||||
img.data = (void *)cbuf_tmp;
|
||||
img.header.cf = LV_COLOR_FORMAT_NATIVE;
|
||||
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_ZOOM_NONE, 0, 0, CANVAS_WIDTH / 2, CANVAS_HEIGHT / 2, true);
|
||||
lv_canvas_finish_layer(canvas, &layer);
|
||||
|
||||
lv_canvas_fill_bg(canvas, lv_palette_lighten(LV_PALETTE_GREY, 1), LV_OPA_COVER);
|
||||
|
||||
lv_draw_img_dsc_t img_dsc;
|
||||
lv_draw_img_dsc_init(&img_dsc);
|
||||
img_dsc.angle = 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_img(&layer, &img_dsc, &coords_img);
|
||||
|
||||
lv_canvas_finish_layer(canvas, &layer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,8 +7,6 @@ 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.bg_grad.stops = [
|
||||
lv.gradient_stop_t({'color': lv.palette_main(lv.PALETTE.RED)}),
|
||||
@@ -25,6 +23,7 @@ rect_dsc.shadow_ofs_y = 5
|
||||
label_dsc = lv.draw_label_dsc_t()
|
||||
label_dsc.init()
|
||||
label_dsc.color = lv.palette_main(lv.PALETTE.ORANGE)
|
||||
label_dsc.text = "Some text on text canvas"
|
||||
|
||||
cbuf = bytearray(_CANVAS_WIDTH * _CANVAS_HEIGHT * 4)
|
||||
# cbuf2 = bytearray(_CANVAS_WIDTH * _CANVAS_HEIGHT * 4)
|
||||
@@ -34,8 +33,29 @@ canvas.set_buffer(cbuf, _CANVAS_WIDTH, _CANVAS_HEIGHT, lv.COLOR_FORMAT.NATIVE)
|
||||
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")
|
||||
layer = lv.layer_t()
|
||||
canvas.init_layer(layer);
|
||||
|
||||
coords_rect = lv.area_t()
|
||||
coords_rect.x1 = 70
|
||||
coords_rect.y1 = 60
|
||||
coords_rect.x2 = 100
|
||||
coords_rect.y2 = 70
|
||||
|
||||
lv.draw_rect(layer, rect_dsc, coords_rect)
|
||||
|
||||
coords_text = lv.area_t()
|
||||
coords_text.x1 = 40
|
||||
coords_text.y1 = 80
|
||||
coords_text.x2 = 100
|
||||
coords_text.y2 = 120
|
||||
|
||||
lv.draw_label(layer, label_dsc, coords_text)
|
||||
|
||||
|
||||
|
||||
canvas.finish_layer(layer)
|
||||
|
||||
|
||||
# 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
|
||||
@@ -43,12 +63,25 @@ canvas.draw_text(40, 20, 100, label_dsc, "Some text on text canvas")
|
||||
img = lv.img_dsc_t()
|
||||
|
||||
img.data = cbuf[:]
|
||||
# cbuf2 = cbuf[:]
|
||||
# img.data = cbuf2
|
||||
img.header.cf = lv.COLOR_FORMAT.NATIVE
|
||||
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, 120, LV_IMG_ZOOM_NONE, 0, 0, _CANVAS_WIDTH // 2, _CANVAS_HEIGHT // 2, True)
|
||||
|
||||
|
||||
img_dsc = lv.draw_img_dsc_t()
|
||||
img_dsc.init();
|
||||
img_dsc.angle = 120;
|
||||
img_dsc.src = img;
|
||||
img_dsc.pivot.x = _CANVAS_WIDTH // 2;
|
||||
img_dsc.pivot.y = _CANVAS_HEIGHT // 2;
|
||||
|
||||
coords_img = lv.area_t()
|
||||
coords_img.x1 = 0
|
||||
coords_img.y1 = 0
|
||||
coords_img.x2 = _CANVAS_WIDTH - 1
|
||||
coords_img.y2 = _CANVAS_HEIGHT - 1
|
||||
|
||||
lv.draw_img(layer, img_dsc, coords_img)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES
|
||||
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES && 0
|
||||
|
||||
#define CANVAS_WIDTH 50
|
||||
#define CANVAS_HEIGHT 50
|
||||
|
||||
@@ -1,45 +1 @@
|
||||
import math
|
||||
|
||||
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(math.floor((w + 7) / 8 ) * 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.COLOR_FORMAT.I1)
|
||||
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.set_int(0)
|
||||
c1.set_int(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, lv.OPA.COVER)
|
||||
pass
|
||||
|
||||
@@ -18,6 +18,9 @@ void lv_example_canvas_3(void)
|
||||
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);
|
||||
@@ -29,8 +32,11 @@ void lv_example_canvas_3(void)
|
||||
dsc.outline_opa = LV_OPA_50;
|
||||
dsc.radius = 5;
|
||||
dsc.border_width = 3;
|
||||
lv_canvas_draw_rect(canvas, 10, 10, 30, 20, &dsc);
|
||||
|
||||
lv_area_t coords = {10, 10, 30, 20};
|
||||
|
||||
lv_draw_rect(&layer, &dsc, &coords);
|
||||
|
||||
lv_canvas_finish_layer(canvas, &layer);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -27,5 +27,18 @@ dsc.outline_pad = 2
|
||||
dsc.outline_opa = lv.OPA._50
|
||||
dsc.radius = 5
|
||||
dsc.border_width = 3
|
||||
canvas.draw_rect(10, 10, 30, 20, dsc)
|
||||
|
||||
|
||||
coords = lv.area_t()
|
||||
coords.x1 = 10
|
||||
coords.y1 = 10
|
||||
coords.x2 = 30
|
||||
coords.y2 = 20
|
||||
|
||||
layer = lv.layer_t()
|
||||
canvas.init_layer(layer);
|
||||
|
||||
lv.draw_rect(layer, dsc, coords)
|
||||
|
||||
canvas.finish_layer(layer)
|
||||
|
||||
|
||||
@@ -18,12 +18,21 @@ void lv_example_canvas_4(void)
|
||||
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_18;
|
||||
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);
|
||||
|
||||
lv_canvas_draw_text(canvas, 10, 10, 30, &dsc, "Hello");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -37,7 +37,7 @@ if script_path != '':
|
||||
# needed for dynamic font loading
|
||||
fs_drv = lv.fs_drv_t()
|
||||
fs_driver.fs_register(fs_drv, 'S')
|
||||
|
||||
|
||||
print("Loading font montserrat_18")
|
||||
font_montserrat_18 = lv.font_load("S:" + script_path + "/../../assets/font/montserrat-18.fnt")
|
||||
if not font_montserrat_18:
|
||||
@@ -46,7 +46,22 @@ if script_path != '':
|
||||
dsc.font = font_montserrat_18
|
||||
|
||||
dsc.decor = lv.TEXT_DECOR.UNDERLINE
|
||||
print('Printing "Hello"')
|
||||
canvas.draw_text(10, 10, 30, dsc, "Hello")
|
||||
dsc.text = "Hello"
|
||||
|
||||
|
||||
layer = lv.layer_t()
|
||||
canvas.init_layer(layer);
|
||||
|
||||
|
||||
coords = lv.area_t()
|
||||
coords.x1 = 10
|
||||
coords.y1 = 10
|
||||
coords.x2 = 40
|
||||
coords.y2 = 30
|
||||
|
||||
|
||||
lv.draw_label(layer, dsc, coords)
|
||||
|
||||
canvas.finish_layer(layer)
|
||||
|
||||
|
||||
|
||||
@@ -18,11 +18,22 @@ void lv_example_canvas_5(void)
|
||||
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 = 15;
|
||||
dsc.start_angle = 0;
|
||||
dsc.end_angle = 220;
|
||||
|
||||
lv_draw_arc(&layer, &dsc);
|
||||
|
||||
lv_canvas_finish_layer(canvas, &layer);
|
||||
|
||||
lv_canvas_draw_arc(canvas, 25, 25, 15, 0, 220, &dsc);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,16 @@ dsc = lv.draw_arc_dsc_t()
|
||||
dsc.init()
|
||||
dsc.color = lv.palette_main(lv.PALETTE.RED)
|
||||
dsc.width = 5
|
||||
dsc.center.x = 25
|
||||
dsc.center.y = 25
|
||||
dsc.width = 15
|
||||
dsc.start_angle = 0
|
||||
dsc.end_angle = 220
|
||||
|
||||
canvas.draw_arc(25, 25, 15, 0, 220, dsc)
|
||||
layer = lv.layer_t()
|
||||
canvas.init_layer(layer);
|
||||
|
||||
lv.draw_arc(layer, dsc)
|
||||
|
||||
canvas.finish_layer(layer)
|
||||
|
||||
|
||||
@@ -18,10 +18,19 @@ void lv_example_canvas_6(void)
|
||||
lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);
|
||||
lv_obj_center(canvas);
|
||||
|
||||
lv_draw_img_dsc_t dsc;
|
||||
lv_draw_img_dsc_init(&dsc);
|
||||
lv_layer_t layer;
|
||||
lv_canvas_init_layer(canvas, &layer);
|
||||
|
||||
LV_IMG_DECLARE(img_star);
|
||||
lv_canvas_draw_img(canvas, 5, 5, &img_star, &dsc);
|
||||
lv_draw_img_dsc_t dsc;
|
||||
lv_draw_img_dsc_init(&dsc);
|
||||
dsc.src = &img_star;
|
||||
|
||||
lv_area_t coords = {5, 5, 5 + img_star.header.w - 1, 10 + img_star.header.h - 1};
|
||||
|
||||
lv_draw_img(&layer, &dsc, &coords);
|
||||
|
||||
lv_canvas_finish_layer(canvas, &layer);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -31,6 +31,20 @@ canvas.center()
|
||||
|
||||
dsc = lv.draw_img_dsc_t()
|
||||
dsc.init()
|
||||
dsc.src = img_star_argb
|
||||
|
||||
canvas.draw_img(5, 5, img_star_argb, dsc)
|
||||
|
||||
|
||||
coords = lv.area_t()
|
||||
coords.x1 = 5
|
||||
coords.y1 = 5
|
||||
coords.x2 = 5 + 29
|
||||
coords.y2 = 5 + 28
|
||||
|
||||
|
||||
layer = lv.layer_t()
|
||||
canvas.init_layer(layer);
|
||||
|
||||
lv.draw_img(layer, dsc, coords)
|
||||
|
||||
canvas.finish_layer(layer)
|
||||
|
||||
@@ -18,14 +18,23 @@ void lv_example_canvas_7(void)
|
||||
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);
|
||||
|
||||
|
||||
lv_point_t p[] = {{15, 15}, {35, 10}, {10, 40}};
|
||||
lv_canvas_draw_line(canvas, p, 3, &dsc);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -23,11 +23,16 @@ 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;
|
||||
|
||||
p = [ {"x":15,"y":15},
|
||||
{"x":35,"y":10},
|
||||
{"x":10,"y":40} ]
|
||||
layer = lv.layer_t()
|
||||
canvas.init_layer(layer);
|
||||
|
||||
canvas.draw_line(p, 3, dsc)
|
||||
lv.draw_line(layer, dsc)
|
||||
|
||||
canvas.finish_layer(layer)
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_CHART && LV_USE_DRAW_MASKS && LV_BUILD_EXAMPLES
|
||||
//TODO should be a chart feature
|
||||
#if LV_USE_CHART && LV_USE_DRAW_MASKS && LV_BUILD_EXAMPLES && 0
|
||||
|
||||
static lv_obj_t * chart1;
|
||||
static lv_chart_series_t * ser1;
|
||||
@@ -10,10 +11,9 @@ 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;
|
||||
|
||||
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) {
|
||||
/*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,
|
||||
@@ -38,7 +38,7 @@ static void draw_event_cb(lv_event_t * e)
|
||||
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);
|
||||
lv_draw_rect(dsc->layer, &draw_rect_dsc, &a);
|
||||
|
||||
/*Remove the masks*/
|
||||
lv_draw_mask_free_param(&line_mask_param);
|
||||
@@ -111,9 +111,10 @@ void lv_example_chart_2(void)
|
||||
|
||||
lv_chart_set_div_line_count(chart1, 5, 7);
|
||||
|
||||
lv_obj_add_event(chart1, draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
|
||||
lv_chart_set_update_mode(chart1, LV_CHART_UPDATE_MODE_CIRCULAR);
|
||||
lv_obj_add_event(chart1, draw_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);
|
||||
lv_obj_add_flag(chart1, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);
|
||||
|
||||
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);
|
||||
|
||||
@@ -1,112 +1 @@
|
||||
def draw_event_cb(e):
|
||||
|
||||
obj = e.get_target_obj()
|
||||
|
||||
# Add the faded area before the lines are drawn
|
||||
# dsc = lv.obj_draw_part_dsc_t.__cast__(e.get_param())
|
||||
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 = 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_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
|
||||
elif dsc.part == lv.PART.MAIN:
|
||||
if dsc.line_dsc == None or dsc.p1 == None or dsc.p2 == None:
|
||||
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 or 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)
|
||||
|
||||
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.set_div_line_count(5, 7)
|
||||
|
||||
chart1.add_event(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)
|
||||
pass
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_CHART && LV_BUILD_EXAMPLES
|
||||
//TODO when lv_scale is ready
|
||||
#if LV_USE_CHART && LV_BUILD_EXAMPLES && 0
|
||||
|
||||
static void draw_event_cb(lv_event_t * e)
|
||||
{
|
||||
|
||||
@@ -1,52 +1 @@
|
||||
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(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
|
||||
|
||||
pass
|
||||
@@ -45,8 +45,8 @@ static void event_cb(lv_event_t * e)
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -5,52 +5,14 @@ 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 void value_changed_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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +28,7 @@ void lv_example_chart_6(void)
|
||||
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(chart, event_cb, LV_EVENT_ALL, NULL);
|
||||
lv_obj_add_event(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);
|
||||
|
||||
@@ -1,87 +1 @@
|
||||
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(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_obj()
|
||||
|
||||
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
|
||||
dsc.draw_ctx.rect(draw_rect_dsc,a)
|
||||
|
||||
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
|
||||
dsc.draw_ctx.label(draw_label_dsc,a,value_txt,None)
|
||||
|
||||
example_chart_6 = ExampleChart_6()
|
||||
pass
|
||||
@@ -3,24 +3,27 @@
|
||||
|
||||
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_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*/
|
||||
dsc->rect_dsc->bg_opa = (LV_OPA_COVER * dsc->id) / (cnt - 1);
|
||||
rect_draw_dsc->bg_opa = (LV_OPA_COVER * base_dsc->id2) / (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*/
|
||||
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;
|
||||
|
||||
dsc->rect_dsc->bg_color = lv_color_mix(lv_palette_main(LV_PALETTE_RED),
|
||||
rect_draw_dsc->bg_color = lv_color_mix(lv_palette_main(LV_PALETTE_RED),
|
||||
lv_palette_main(LV_PALETTE_BLUE),
|
||||
x_opa + y_opa);
|
||||
}
|
||||
@@ -41,7 +44,8 @@ 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(chart, draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
|
||||
lv_obj_add_event(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);
|
||||
|
||||
@@ -1,76 +1 @@
|
||||
#!/opt/bin/lv_micropython -i
|
||||
import utime as time
|
||||
import lvgl as lv
|
||||
|
||||
def draw_event_cb(e):
|
||||
dsc = e.get_draw_part_dsc()
|
||||
if dsc.part == lv.PART.ITEMS:
|
||||
obj = e.get_target_obj()
|
||||
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(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))
|
||||
pass
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_CHART && LV_USE_DRAW_MASKS && LV_BUILD_EXAMPLES
|
||||
//TODO Should be a chart feature
|
||||
#if LV_USE_CHART && LV_USE_DRAW_MASKS && LV_BUILD_EXAMPLES && 0
|
||||
|
||||
/* 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 {
|
||||
@@ -40,7 +41,7 @@ static void draw_event_cb(lv_event_t * e)
|
||||
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);
|
||||
lv_draw_rect(dsc->layer, &draw_rect_dsc, &a);
|
||||
|
||||
/*Remove the mask*/
|
||||
lv_draw_mask_free_param(&line_mask_param);
|
||||
|
||||
@@ -1,123 +1 @@
|
||||
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_obj()
|
||||
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( 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, 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()
|
||||
pass
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
Simple Colorwheel
|
||||
-----------------
|
||||
|
||||
.. lv_example:: widgets/colorwheel/lv_example_colorwheel_1
|
||||
:language: c
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#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
|
||||
@@ -1,4 +0,0 @@
|
||||
cw = lv.colorwheel(lv.scr_act(), True)
|
||||
cw.set_size(200, 200)
|
||||
cw.center()
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
void lv_example_img_1(void)
|
||||
{
|
||||
LV_IMG_DECLARE(img_cogwheel_chroma_keyed);
|
||||
LV_IMG_DECLARE(img_cogwheel_argb);
|
||||
lv_obj_t * img1 = lv_img_create(lv_scr_act());
|
||||
lv_img_set_src(img1, &img_cogwheel_chroma_keyed);
|
||||
lv_img_set_src(img1, &img_cogwheel_argb);
|
||||
lv_obj_align(img1, LV_ALIGN_CENTER, 0, -20);
|
||||
lv_obj_set_size(img1, 200, 200);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ def create_slider(color):
|
||||
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.set_style_bg_color(color.darken(lv.OPA._40), lv.PART.INDICATOR)
|
||||
slider.add_event(slider_event_cb, lv.EVENT.VALUE_CHANGED, None)
|
||||
return slider
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_LABEL && LV_USE_CANVAS && LV_BUILD_EXAMPLES && LV_USE_DRAW_MASKS
|
||||
//TODO
|
||||
#if LV_USE_LABEL && LV_USE_CANVAS && LV_BUILD_EXAMPLES && LV_USE_DRAW_MASKS && 0
|
||||
|
||||
#define MASK_WIDTH 100
|
||||
#define MASK_HEIGHT 45
|
||||
@@ -44,7 +45,8 @@ void lv_example_label_4(void)
|
||||
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");
|
||||
label_dsc.text = "Text with gradient";
|
||||
lv_canvas_draw_text(canvas, 5, 5, MASK_WIDTH, &label_dsc);
|
||||
|
||||
/*The mask is reads the canvas is not required anymore*/
|
||||
lv_obj_del(canvas);
|
||||
|
||||
@@ -1,63 +1 @@
|
||||
MASK_WIDTH = 100
|
||||
MASK_HEIGHT = 45
|
||||
|
||||
def add_mask_event_cb(e,mask_map):
|
||||
|
||||
code = e.get_code()
|
||||
obj = e.get_target_obj()
|
||||
|
||||
if code == lv.EVENT.COVER_CHECK :
|
||||
e.set_cover_res(lv.COVER_RES.MASKED)
|
||||
|
||||
elif code == lv.EVENT.DRAW_MAIN_BEGIN:
|
||||
m = lv.draw_mask_map_param_t()
|
||||
obj_coords = lv.area_t()
|
||||
obj.get_coords(obj_coords)
|
||||
m.init(obj_coords, mask_map)
|
||||
mask_id = lv.draw_mask_add(m,None)
|
||||
|
||||
elif code == lv.EVENT.DRAW_MAIN_END:
|
||||
try:
|
||||
m.free_param()
|
||||
mask_id.remove_id()
|
||||
except:
|
||||
pass
|
||||
|
||||
#
|
||||
# Draw label with gradient color
|
||||
#
|
||||
# Create the mask of a text by drawing it to a canvas
|
||||
mask_map = bytearray(MASK_WIDTH * MASK_HEIGHT * 4)
|
||||
|
||||
# Create a "8 bit alpha" canvas and clear it
|
||||
canvas = lv.canvas(lv.scr_act())
|
||||
canvas.set_buffer(mask_map, MASK_WIDTH, MASK_HEIGHT, lv.COLOR_FORMAT.NATIVE)
|
||||
canvas.fill_bg(lv.color_black(), lv.OPA.TRANSP)
|
||||
|
||||
# Draw a label to the canvas. The result "image" will be used as mask
|
||||
label_dsc = lv.draw_label_dsc_t()
|
||||
label_dsc.init()
|
||||
label_dsc.color = lv.color_white()
|
||||
label_dsc.align = lv.TEXT_ALIGN.CENTER
|
||||
canvas.draw_text(5, 5, MASK_WIDTH, label_dsc, "Text with gradient")
|
||||
|
||||
# The mask is reads the canvas is not required anymore
|
||||
canvas.delete()
|
||||
|
||||
# Convert the mask to A8
|
||||
# This is just a work around and will be changed later
|
||||
mask8 = bytearray(MASK_WIDTH * MASK_HEIGHT)
|
||||
for i in range(MASK_WIDTH * MASK_HEIGHT):
|
||||
#mask8[i] = lv.color_brightness(mask_c[i]);
|
||||
mask8[i] = mask_map[4*i]
|
||||
|
||||
# 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
|
||||
grad = lv.obj(lv.scr_act())
|
||||
grad.set_size( MASK_WIDTH, MASK_HEIGHT)
|
||||
grad.center()
|
||||
grad.set_style_bg_color(lv.color_hex(0xff0000), 0)
|
||||
grad.set_style_bg_grad_color(lv.color_hex(0x0000ff), 0)
|
||||
grad.set_style_bg_grad_dir(lv.GRAD_DIR.HOR, 0)
|
||||
grad.add_event(lambda e: add_mask_event_cb(e,mask8), lv.EVENT.ALL, None)
|
||||
|
||||
pass
|
||||
@@ -20,7 +20,6 @@ void lv_example_list_1(void)
|
||||
|
||||
/*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(btn, event_handler, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
@@ -80,10 +80,10 @@ LV_MENU_ITEM_BUILDER_VARIANT_2 = const(1)
|
||||
menu = lv.menu(lv.scr_act())
|
||||
|
||||
bg_color = menu.get_style_bg_color(0)
|
||||
if bg_color.color_brightness() > 127 :
|
||||
menu.set_style_bg_color(menu.get_style_bg_color(0).color_darken(10),0)
|
||||
if bg_color.brightness() > 127 :
|
||||
menu.set_style_bg_color(menu.get_style_bg_color(0).darken(10),0)
|
||||
else :
|
||||
menu.set_style_bg_color(menu.get_style_bg_color(0).color_darken(50),0)
|
||||
menu.set_style_bg_color(menu.get_style_bg_color(0).darken(50),0)
|
||||
|
||||
|
||||
menu.set_mode_root_back_btn(lv.menu.ROOT_BACK_BTN.ENABLED)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_METER && LV_BUILD_EXAMPLES
|
||||
//TODO
|
||||
#if LV_USE_METER && LV_BUILD_EXAMPLES && 0
|
||||
|
||||
static lv_obj_t * meter;
|
||||
|
||||
|
||||
@@ -1,85 +1 @@
|
||||
import utime as time
|
||||
|
||||
# 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
|
||||
#
|
||||
|
||||
def tick_label_event(e):
|
||||
draw_part_dsc = e.get_draw_part_dsc();
|
||||
|
||||
# Be sure it's drawing the ticks
|
||||
if draw_part_dsc.type != lv.meter.DRAW_PART.TICK: return
|
||||
|
||||
# Be sure it's a major ticks
|
||||
if draw_part_dsc.id % 5: return
|
||||
|
||||
# The order of numbers on the clock is tricky: 12, 1, 2, 3...*/
|
||||
txt = ["12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]
|
||||
# dsc.text is defined char text[16], I must therefore convert the Python string to a byte_array
|
||||
|
||||
idx = int(draw_part_dsc.id / 5)
|
||||
draw_part_dsc.text = bytes(txt[idx],"ascii")
|
||||
|
||||
meter = lv.meter(lv.scr_act())
|
||||
meter.set_size(220, 220)
|
||||
meter.center()
|
||||
|
||||
# Create a scale for the minutes
|
||||
# 60 ticks in a 354 degrees range
|
||||
meter.set_scale_ticks(60, 1, 10, lv.palette_main(lv.PALETTE.GREY))
|
||||
meter.set_scale_major_ticks(5, 2, 20, lv.color_black(), 10) # Every tick is major
|
||||
meter.set_scale_range(0, 59, 354, 270)
|
||||
|
||||
# Add the hands from images
|
||||
indic_min = meter.add_needle_img(img_hand_min_dsc, 5, 5)
|
||||
indic_hour = meter.add_needle_img(img_hand_hour_dsc, 5, 5)
|
||||
|
||||
#Add an event to set the numbers of hours
|
||||
meter.add_event(tick_label_event, lv.EVENT.DRAW_PART_BEGIN, None)
|
||||
|
||||
# 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)
|
||||
|
||||
pass
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_ROLLER && LV_USE_DRAW_MASKS && LV_BUILD_EXAMPLES
|
||||
//TODO
|
||||
#if LV_USE_ROLLER && LV_USE_DRAW_MASKS && LV_BUILD_EXAMPLES && 0
|
||||
|
||||
static void mask_event_cb(lv_event_t * e)
|
||||
{
|
||||
@@ -92,5 +93,4 @@ void lv_example_roller_3(void)
|
||||
lv_roller_set_visible_row_count(roller1, 3);
|
||||
lv_obj_add_event(roller1, mask_event_cb, LV_EVENT_ALL, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,110 +1 @@
|
||||
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")
|
||||
|
||||
# get the directory in which the script is running
|
||||
try:
|
||||
script_path = __file__[:__file__.rfind('/')] if __file__.find('/') >= 0 else '.'
|
||||
except NameError:
|
||||
print("Could not find script path")
|
||||
script_path = ''
|
||||
if script_path != '':
|
||||
try:
|
||||
font_montserrat_22 = lv.font_load("S:" + script_path + "/../../assets/font/montserrat-22.fnt")
|
||||
roller1.set_style_text_font(font_montserrat_22,lv.PART.SELECTED)
|
||||
except:
|
||||
print("Cannot load font file montserrat-22.fnt")
|
||||
|
||||
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(self.mask_event_cb, lv.EVENT.ALL, None)
|
||||
|
||||
def mask_event_cb(self,e):
|
||||
|
||||
code = e.get_code()
|
||||
obj = e.get_target_obj()
|
||||
|
||||
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()
|
||||
pass
|
||||
@@ -31,25 +31,31 @@ static void slider_event_cb(lv_event_t * e)
|
||||
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));
|
||||
else if(code == LV_EVENT_DRAW_MAIN_END) {
|
||||
if(!lv_obj_has_state(obj, LV_STATE_PRESSED)) return;
|
||||
|
||||
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_slider_t * slider = (lv_slider_t *) obj;
|
||||
const lv_area_t * indic_area = &slider->bar.indic_area;
|
||||
char buf[16];
|
||||
lv_snprintf(buf, sizeof(buf), "%d - %d", (int)lv_slider_get_left_value(obj), (int)lv_slider_get_value(obj));
|
||||
|
||||
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);
|
||||
}
|
||||
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 = 0;
|
||||
label_area.x2 = label_size.x - 1;
|
||||
label_area.y1 = 0;
|
||||
label_area.y2 = label_size.y - 1;
|
||||
|
||||
lv_area_align(indic_area, &label_area, LV_ALIGN_OUT_TOP_MID, 0, -10);
|
||||
|
||||
lv_draw_label_dsc_t label_draw_dsc;
|
||||
lv_draw_label_dsc_init(&label_draw_dsc);
|
||||
label_draw_dsc.color = lv_color_hex3(0x888);
|
||||
label_draw_dsc.text = buf;
|
||||
label_draw_dsc.text_local = true;
|
||||
lv_layer_t * layer = lv_event_get_layer(e);
|
||||
lv_draw_label(layer, &label_draw_dsc, &label_area);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,25 +6,26 @@ def slider_event_cb(e):
|
||||
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:
|
||||
elif code == lv.EVENT.DRAW_TASK_ADDED:
|
||||
dsc = e.get_draw_task()
|
||||
base_dsc = lv.draw_dsc_base_t.__cast__(dsc.draw_dsc)
|
||||
if base_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.x1 = dsc.area.x1 + dsc.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.y2 = dsc.area.y1 - 10
|
||||
label_area.y1 = label_area.y2 - label_size.y
|
||||
|
||||
label_draw_dsc = lv.draw_label_dsc_t()
|
||||
label_draw_dsc.init()
|
||||
label_draw_dsc.text = label_text
|
||||
label_draw_dsc.text_local = 1
|
||||
|
||||
dsc.draw_ctx.label(label_draw_dsc, label_area, label_text, None)
|
||||
lv.draw_label(base_dsc.layer, label_draw_dsc, label_area)
|
||||
#
|
||||
# Show the current value when the slider if pressed by extending the drawer
|
||||
#
|
||||
@@ -39,5 +40,6 @@ slider.set_value(70, lv.ANIM.OFF)
|
||||
slider.set_left_value(20, lv.ANIM.OFF)
|
||||
|
||||
slider.add_event(slider_event_cb, lv.EVENT.ALL, None)
|
||||
slider.add_flag(lv.obj.FLAG.SEND_DRAW_TASK_EVENTS)
|
||||
slider.refresh_ext_draw_size()
|
||||
|
||||
|
||||
@@ -1,30 +1,42 @@
|
||||
#include "../../lv_examples.h"
|
||||
#if LV_USE_TABLE && LV_BUILD_EXAMPLES
|
||||
|
||||
static void draw_part_event_cb(lv_event_t * e)
|
||||
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);
|
||||
lv_draw_task_t * draw_task = lv_event_get_draw_task(e);
|
||||
lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;
|
||||
/*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);
|
||||
if(base_dsc->part == LV_PART_ITEMS) {
|
||||
uint32_t row = base_dsc->id1;
|
||||
uint32_t col = base_dsc->id2;
|
||||
|
||||
/*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;
|
||||
if(draw_task->type == LV_DRAW_TASK_TYPE_LABEL) {
|
||||
lv_draw_label_dsc_t * label_draw_dsc = draw_task->draw_dsc;
|
||||
label_draw_dsc->align = LV_TEXT_ALIGN_CENTER;
|
||||
}
|
||||
if(draw_task->type == LV_DRAW_TASK_TYPE_FILL) {
|
||||
lv_draw_rect_dsc_t * rect_draw_dsc = draw_task->draw_dsc;
|
||||
rect_draw_dsc->bg_color = lv_color_mix(lv_palette_main(LV_PALETTE_BLUE), rect_draw_dsc->bg_color, LV_OPA_20);
|
||||
rect_draw_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;
|
||||
if(draw_task->type == LV_DRAW_TASK_TYPE_LABEL) {
|
||||
lv_draw_label_dsc_t * label_draw_dsc = draw_task->draw_dsc;
|
||||
label_draw_dsc->align = LV_TEXT_ALIGN_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
/*MAke every 2nd row grayish*/
|
||||
/*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;
|
||||
if(draw_task->type == LV_DRAW_TASK_TYPE_FILL) {
|
||||
lv_draw_rect_dsc_t * rect_draw_dsc = draw_task->draw_dsc;
|
||||
rect_draw_dsc->bg_color = lv_color_mix(lv_palette_main(LV_PALETTE_GREY), rect_draw_dsc->bg_color, LV_OPA_10);
|
||||
rect_draw_dsc->bg_opa = LV_OPA_COVER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,7 +71,8 @@ void lv_example_table_1(void)
|
||||
lv_obj_center(table);
|
||||
|
||||
/*Add an event callback to to apply some custom drawing*/
|
||||
lv_obj_add_event(table, draw_part_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
|
||||
lv_obj_add_event(table, draw_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);
|
||||
lv_obj_add_flag(table, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,53 +1 @@
|
||||
def draw_part_event_cb(e):
|
||||
obj = e.get_target_obj()
|
||||
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(draw_part_event_cb, lv.EVENT.DRAW_PART_BEGIN, None)
|
||||
|
||||
pass
|
||||
@@ -6,35 +6,40 @@
|
||||
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_task_t * draw_task = lv_event_get_draw_task(e);
|
||||
lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;
|
||||
/*If the cells are drawn...*/
|
||||
if(base_dsc->part == LV_PART_ITEMS && draw_task->type == LV_DRAW_TASK_TYPE_FILL) {
|
||||
/*Draw the background*/
|
||||
bool chk = lv_table_has_cell_ctrl(obj, base_dsc->id1, 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);
|
||||
sw_area.x1 = 0;
|
||||
sw_area.x2 = 40;
|
||||
sw_area.y1 = 0;
|
||||
sw_area.y2 = 24;
|
||||
lv_area_align(&draw_task->area, &sw_area, LV_ALIGN_RIGHT_MID, -15, 0);
|
||||
lv_draw_rect(base_dsc->layer, &rect_dsc, &sw_area);
|
||||
|
||||
/*Draw the knob*/
|
||||
rect_dsc.bg_color = lv_color_white();
|
||||
lv_area_t knob_area;
|
||||
knob_area.x1 = 0;
|
||||
knob_area.x2 = 18;
|
||||
knob_area.y1 = 0;
|
||||
knob_area.y2 = 18;
|
||||
if(chk) {
|
||||
sw_area.x2 -= 2;
|
||||
sw_area.x1 = sw_area.x2 - 16;
|
||||
lv_area_align(&sw_area, &knob_area, LV_ALIGN_RIGHT_MID, -3, 0);
|
||||
}
|
||||
else {
|
||||
sw_area.x1 += 2;
|
||||
sw_area.x2 = sw_area.x1 + 16;
|
||||
lv_area_align(&sw_area, &knob_area, LV_ALIGN_LEFT_MID, 3, 0);
|
||||
}
|
||||
sw_area.y1 += 2;
|
||||
sw_area.y2 -= 2;
|
||||
lv_draw_rect(dsc->draw_ctx, &rect_dsc, &sw_area);
|
||||
lv_draw_rect(base_dsc->layer, &rect_dsc, &knob_area);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,8 +86,9 @@ void lv_example_table_2(void)
|
||||
lv_obj_align(table, LV_ALIGN_CENTER, 0, -20);
|
||||
|
||||
/*Add an event callback to to apply some custom drawing*/
|
||||
lv_obj_add_event(table, draw_event_cb, LV_EVENT_DRAW_PART_END, NULL);
|
||||
lv_obj_add_event(table, draw_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);
|
||||
lv_obj_add_event(table, change_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
lv_obj_add_flag(table, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);
|
||||
|
||||
lv_mem_monitor_t mon2;
|
||||
lv_mem_monitor(&mon2);
|
||||
|
||||
@@ -1,95 +1 @@
|
||||
from utime import ticks_ms
|
||||
import gc
|
||||
|
||||
ITEM_CNT = 200
|
||||
|
||||
def draw_event_cb(e):
|
||||
obj = e.get_target_obj()
|
||||
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_obj()
|
||||
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(draw_event_cb, lv.EVENT.DRAW_PART_END, None)
|
||||
table.add_event(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)
|
||||
pass
|
||||
Reference in New Issue
Block a user