南昌做网站建设哪家好凤山网站seo
因为工作需要用LVGL实现了一个简易的画图板
LVGL版本:8.2
主要功能有画图,选择画笔颜色,设置画笔宽度,画图板清空
代码如下:
#ifndef __LV_OBJ_SKETCHPAD_H__
#define __LV_OBJ_SKETCHPAD_H__#include "lvgl/lvgl.h"#ifdef __cplusplus
extern "C" {
#endif#define SKETCHPAD_DEFAULT_WIDTH (800)
#define SKETCHPAD_DEFAULT_HEIGHT (480)typedef enum {LV_SKETCHPAD_TOOLBAR_OPT_ALL = 0,LV_SKETCHPAD_TOOLBAR_OPT_COOLWHEEL, // 色轮LV_SKETCHPAD_TOOLBAR_OPT_WIDTH, // 画笔宽度调节LV_SKETCHPAD_TOOLBAR_OPT_CLEAR, // 清空画布LV_SKETCHPAD_TOOLBAR_OPT_LAST
}lv_100ask_sketchpad_toolbar_e;/*Data of canvas*/
typedef struct {lv_img_t img;lv_img_dsc_t dsc;lv_draw_line_dsc_t line_rect_dsc;
} lv_obj_sketchpad_t;/************************ GLOBAL VARIABLES***********************//*********************** GLOBAL PROTOTYPES**********************/
lv_obj_t* lv_obj_sketchpad_create(lv_obj_t* parent);void lv_gui_sketchpad_display();#ifdef __cplusplus
} /*extern "C"*/
#endif#endif // __LV_GUI_SKETCHPAD_H__
#include "lv_obj_sketchpad.h"/********************** DEFINES*********************/
#define THIS_FILE "lv_obj_sketchpad.c"
#define MY_CLASS &lv_obj_sketchpad_class/*********************** TYPEDEFS**********************//*********************** STATIC PROTOTYPES**********************/
static void lv_obj_sketchpad_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj);
static void lv_obj_sketchpad_destructor(const lv_obj_class_t* class_p, lv_obj_t* obj);static void lv_sketchpad_toolbar_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj);
static void lv_sketchpad_toolbar_destructor(const lv_obj_class_t* class_p, lv_obj_t* obj);static void lv_obj_sketchpad_event(const lv_obj_class_t* class_p, lv_event_t* e);
static void lv_sketchpad_toolbar_event(const lv_obj_class_t* class_p, lv_event_t* e);static void sketchpad_toolbar_event_cb(lv_event_t* e);
static void toolbar_set_event_cb(lv_event_t* e);/*********************** STATIC VARIABLES**********************/
const lv_obj_class_t lv_obj_sketchpad_class = {.constructor_cb = lv_obj_sketchpad_constructor,.destructor_cb = lv_obj_sketchpad_destructor,.event_cb = lv_obj_sketchpad_event,.width_def = LV_PCT(100), // 默认宽度.height_def = LV_PCT(100), // 默认高度.instance_size = sizeof(lv_obj_sketchpad_t),.base_class = &lv_canvas_class
};const lv_obj_class_t lv_sketchpad_toolbar_class = {.constructor_cb = lv_sketchpad_toolbar_constructor,.destructor_cb = lv_sketchpad_toolbar_destructor,.event_cb = lv_sketchpad_toolbar_event,.width_def = LV_SIZE_CONTENT,.height_def = LV_SIZE_CONTENT,.base_class = &lv_obj_class
};/*********************** MACROS**********************//*********************** GLOBAL FUNCTIONS**********************/lv_obj_t* lv_obj_sketchpad_create(lv_obj_t* parent)
{LV_LOG_INFO("begin");lv_obj_t* obj = lv_obj_class_create_obj(MY_CLASS, parent);lv_obj_class_init_obj(obj);return obj;
}/*=====================* Other functions*====================*//*********************** STATIC FUNCTIONS**********************/static void lv_obj_sketchpad_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
{LV_UNUSED(class_p);LV_TRACE_OBJ_CREATE("begin");if (obj == NULL)return;lv_obj_sketchpad_t* sketchpad = (lv_obj_sketchpad_t *)obj;sketchpad->dsc.header.always_zero = 0;sketchpad->dsc.header.cf = LV_IMG_CF_TRUE_COLOR;sketchpad->dsc.header.h = 0;sketchpad->dsc.header.w = 0;sketchpad->dsc.data_size = 0;sketchpad->dsc.data = NULL;lv_draw_line_dsc_init(&sketchpad->line_rect_dsc);sketchpad->line_rect_dsc.width = 2;sketchpad->line_rect_dsc.round_start = true;sketchpad->line_rect_dsc.round_end = true;sketchpad->line_rect_dsc.color = lv_color_make(0xFF, 0x0, 0x00);sketchpad->line_rect_dsc.opa = LV_OPA_COVER;lv_img_set_src(obj, &sketchpad->dsc);lv_obj_add_flag(obj, LV_OBJ_FLAG_CLICKABLE); // 添加点击属性/*toolbar 基于sketchpad创建toolbar*/lv_obj_t* toolbar = lv_obj_class_create_obj(&lv_sketchpad_toolbar_class, obj);lv_obj_class_init_obj(toolbar);LV_TRACE_OBJ_CREATE("finished");
}static void lv_obj_sketchpad_destructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
{LV_UNUSED(class_p);LV_TRACE_OBJ_CREATE("begin");if (obj == NULL)return;lv_canvas_t* canvas = (lv_canvas_t*)obj;lv_img_cache_invalidate_src(&canvas->dsc);LV_TRACE_OBJ_CREATE("finished");
}static void lv_obj_sketchpad_event(const lv_obj_class_t* class_p, lv_event_t* e)
{LV_UNUSED(class_p);/*Call the ancestor's event handler*/lv_res_t res = lv_obj_event_base(MY_CLASS, e);if (res != LV_RES_OK)return;lv_event_code_t code = lv_event_get_code(e);lv_obj_t* obj = lv_event_get_target(e);lv_obj_sketchpad_t* sketchpad = (lv_obj_sketchpad_t*)obj;static lv_coord_t last_x = 0, last_y = -32768;if (code == LV_EVENT_PRESSING){lv_indev_t* indev = lv_indev_get_act();if (indev == NULL) return;lv_point_t point;lv_indev_get_point(indev, &point);lv_point_t points[2] = { 0 };/*Release or first use*/if ((last_x == -32768) || (last_y == -32768)){last_x = point.x;last_y = point.y;}else{points[0].x = last_x;points[0].y = last_y;points[1].x = point.x;points[1].y = point.y;last_x = point.x;last_y = point.y;lv_canvas_draw_line(obj, points, 2, &sketchpad->line_rect_dsc);}}/*Loosen the brush*/else if (code == LV_EVENT_RELEASED){last_x = -32768;last_y = -32768;}
}/*toolbar*/
static void lv_sketchpad_toolbar_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
{LV_UNUSED(class_p);LV_TRACE_OBJ_CREATE("begin");lv_obj_add_flag(obj, LV_OBJ_FLAG_CLICKABLE); // 添加可点击属性lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); // 移除可滚动属性// 设置流式布局lv_obj_set_flex_grow(obj, 1);lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_ROW);lv_obj_set_size(obj, 60, 20);lv_obj_align(obj, LV_ALIGN_TOP_MID, 0, 0);// 颜色选择static lv_coord_t sketchpad_toolbar_colorwheel = LV_SKETCHPAD_TOOLBAR_OPT_COOLWHEEL;lv_obj_t* color_edit = lv_label_create(obj);lv_label_set_text(color_edit, LV_SYMBOL_EDIT);lv_obj_add_flag(color_edit, LV_OBJ_FLAG_CLICKABLE);lv_obj_set_size(color_edit, 20, 20);lv_obj_add_event_cb(color_edit, sketchpad_toolbar_event_cb, LV_EVENT_ALL, (void*)&sketchpad_toolbar_colorwheel);// 画笔宽度static lv_coord_t sketchpad_toolbar_width = LV_SKETCHPAD_TOOLBAR_OPT_WIDTH;lv_obj_t* pen_size = lv_label_create(obj);lv_label_set_text(pen_size, LV_SYMBOL_EJECT);lv_obj_add_flag(pen_size, LV_OBJ_FLAG_CLICKABLE);lv_obj_set_size(pen_size, 20, 20);lv_obj_add_event_cb(pen_size, sketchpad_toolbar_event_cb, LV_EVENT_ALL, (void*)&sketchpad_toolbar_width);// 清空按钮static lv_coord_t sketchpad_toolbar_clear = LV_SKETCHPAD_TOOLBAR_OPT_CLEAR;lv_obj_t* clear_obj = lv_label_create(obj);lv_label_set_text(clear_obj, LV_SYMBOL_TRASH);lv_obj_add_flag(clear_obj, LV_OBJ_FLAG_CLICKABLE);lv_obj_set_size(clear_obj, 20, 20);lv_obj_add_event_cb(clear_obj, sketchpad_toolbar_event_cb, LV_EVENT_CLICKED, (void*)&sketchpad_toolbar_clear);LV_TRACE_OBJ_CREATE("finished");
}static void lv_sketchpad_toolbar_destructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
{}static void lv_sketchpad_toolbar_event(const lv_obj_class_t* class_p, lv_event_t* e)
{LV_UNUSED(class_p);/*Call the ancestor's event handler*/lv_res_t res = lv_obj_event_base(MY_CLASS, e);if (res != LV_RES_OK)return;lv_event_code_t code = lv_event_get_code(e);lv_obj_t* obj = lv_event_get_target(e);if (code == LV_EVENT_PRESSING){lv_indev_t* indev = lv_indev_get_act();if (indev == NULL)return;lv_point_t vect;lv_indev_get_vect(indev, &vect);lv_coord_t x = lv_obj_get_x(obj) + vect.x;lv_coord_t y = lv_obj_get_y(obj) + vect.y;lv_obj_set_pos(obj, x, y);}
}static void sketchpad_toolbar_event_cb(lv_event_t* e)
{lv_coord_t* toolbar_opt = (lv_coord_t *)lv_event_get_user_data(e);lv_event_code_t code = lv_event_get_code(e);lv_obj_t* obj = lv_event_get_target(e);lv_obj_t* toolbar = lv_obj_get_parent(obj);lv_obj_t* sketchpad = lv_obj_get_parent(toolbar);lv_obj_sketchpad_t* sketchpad_obj = (lv_obj_sketchpad_t*)sketchpad;if (code == LV_EVENT_CLICKED){if ((*toolbar_opt) == LV_SKETCHPAD_TOOLBAR_OPT_COOLWHEEL){static lv_coord_t sketchpad_toolbar_cw = LV_SKETCHPAD_TOOLBAR_OPT_COOLWHEEL;lv_obj_t* colorwheel = lv_colorwheel_create(sketchpad, true);lv_obj_align_to(colorwheel, obj, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);lv_obj_add_event_cb(colorwheel, toolbar_set_event_cb, LV_EVENT_RELEASED, &sketchpad_toolbar_cw);}else if ((*toolbar_opt) == LV_SKETCHPAD_TOOLBAR_OPT_WIDTH){static lv_coord_t sketchpad_toolbar_width = LV_SKETCHPAD_TOOLBAR_OPT_WIDTH;lv_obj_t* slider = lv_slider_create(sketchpad);lv_slider_set_value(slider, (int32_t)(sketchpad_obj->line_rect_dsc.width), LV_ANIM_OFF);lv_obj_align_to(slider, obj, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);lv_obj_add_event_cb(slider, toolbar_set_event_cb, LV_EVENT_ALL, &sketchpad_toolbar_width);}else if ((*toolbar_opt) == LV_SKETCHPAD_TOOLBAR_OPT_CLEAR){//lv_canvas_fill_bg(sketchpad, lv_palette_lighten(LV_PALETTE_GREY, 3), LV_OPA_COVER);lv_canvas_fill_bg(sketchpad, lv_color_make(0xFF, 0xFF, 0xFF), LV_OPA_COVER);}}
}static void toolbar_set_event_cb(lv_event_t* e)
{lv_coord_t* toolbar_opt = (lv_coord_t *)lv_event_get_user_data(e);lv_event_code_t code = lv_event_get_code(e);lv_obj_t* obj = lv_event_get_target(e);lv_obj_sketchpad_t* sketchpad_obj = (lv_obj_sketchpad_t*)lv_obj_get_parent(obj);if (code == LV_EVENT_RELEASED){if ((*toolbar_opt) == LV_SKETCHPAD_TOOLBAR_OPT_COOLWHEEL){sketchpad_obj->line_rect_dsc.color = lv_colorwheel_get_rgb(obj);lv_obj_del(obj);}else if (*(toolbar_opt) == LV_SKETCHPAD_TOOLBAR_OPT_WIDTH){lv_obj_del(obj);}}else if (code == LV_EVENT_VALUE_CHANGED){if ((*toolbar_opt) == LV_SKETCHPAD_TOOLBAR_OPT_WIDTH){sketchpad_obj->line_rect_dsc.width = (lv_coord_t)lv_slider_get_value(obj);}}
}void lv_gui_sketchpad_display()
{static lv_color_t color_buf[LV_CANVAS_BUF_SIZE_TRUE_COLOR(SKETCHPAD_DEFAULT_WIDTH, SKETCHPAD_DEFAULT_HEIGHT)] = { 0 };lv_obj_t* sketchpad = lv_obj_sketchpad_create(lv_scr_act());if (sketchpad != NULL){lv_canvas_set_buffer(sketchpad, color_buf, SKETCHPAD_DEFAULT_WIDTH, SKETCHPAD_DEFAULT_HEIGHT, LV_IMG_CF_TRUE_COLOR);//lv_obj_set_size(sketchpad, SKETCHPAD_DEFAULT_WIDTH, SKETCHPAD_DEFAULT_HEIGHT);lv_obj_center(sketchpad);//lv_canvas_fill_bg(sketchpad, lv_palette_lighten(LV_PALETTE_GREY, 3), LV_OPA_COVER);lv_canvas_fill_bg(sketchpad, lv_color_make(0xFF,0xFF,0xFF), LV_OPA_COVER); }
}
运行效果:
参考文档:
lv_100ask_sketchpad