一、组件分析
const lv_obj_class_t lv_barcode_class = {
.constructor_cb = lv_barcode_constructor,
.destructor_cb = lv_barcode_destructor,
.width_def = LV_BARCODE_OBJ_WIDE,
.height_def = LV_BARCODE_OBJ_HIDE,
.instance_size = sizeof(lv_barcode_t),
.base_class = &lv_obj_class
};
lv_barcode_class 就是自定义的条形码组件(类)
里面组成就是类的成员及实现方法
具体可以参考C++中的类和对象
二、源码
lv_barcode.c
/**
* @file lv_barcode.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_barcode.h"
#if LV_USE_BARCODE != 0
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
/*********************
* DEFINES
*********************/
#define MY_CLASS &lv_barcode_class
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void lv_barcode_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static void lv_barcode_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
/**********************
* STATIC VARIABLES
**********************/
const lv_obj_class_t lv_barcode_class = {
.constructor_cb = lv_barcode_constructor,
.destructor_cb = lv_barcode_destructor,
.width_def = LV_BARCODE_OBJ_WIDE,
.height_def = LV_BARCODE_OBJ_HIDE,
.instance_size = sizeof(lv_barcode_t),
.base_class = &lv_obj_class
};
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Create an empty barcode (an `img`) object.
* @param parent point to an object where to create the barcode
* @return pointer to the created barcode object
*/
lv_obj_t * lv_barcode_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;
}
/**
* Set the data of a barcode object
* @param barcode pointer to barcode object
* @param data data to display
* @param width barcode width
* @param height barcode height
*/
void lv_barcode_update(lv_obj_t * obj, const char *data, uint32_t width, uint32_t height)
{
lv_barcode_t * barcode = (lv_barcode_t *)obj;
lv_img_dsc_t * dsc = lv_barcode_get_imgdsc(obj);
if(barcode->have_update == true)
{
lv_mem_free(dsc->data);
barcode->have_update = false;
lv_memset(dsc, 0, sizeof(lv_img_dsc_t));
}
lv_obj_set_size(barcode->barcode_bg, width * 10 / 9, height * 10 / 8);
generate_barcode_image(obj, data, width, height);
}
/*=====================
* Setter functions
*====================*/
void lv_barcode_set_bg_color(lv_obj_t * obj, lv_color_t new_color)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_obj_t * img = lv_barcode_get_img(obj);
lv_barcode_t * barcode = (lv_barcode_t *)obj;
lv_img_dsc_t * dsc = lv_barcode_get_imgdsc(obj);
lv_color_t bg_color = lv_barcode_get_bg_color(obj);
if(barcode->have_update != true)
{
barcode->bg_color = new_color;
return ;
}
lv_color_t *img_buf = (lv_color_t *)dsc->data;
for (int i = 0; i < dsc->header.w * dsc->header.h; i++)
{
if(memcmp(&img_buf[i], &bg_color, sizeof(lv_color_t)) == false)
img_buf[i] = new_color;
}
barcode->bg_color = new_color;
lv_img_set_src(img, dsc);
}
void lv_barcode_set_data_color(lv_obj_t * obj, lv_color_t new_color)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_obj_t * img = lv_barcode_get_img(obj);
lv_barcode_t * barcode = (lv_barcode_t *)obj;
lv_img_dsc_t * dsc = lv_barcode_get_imgdsc(obj);
lv_color_t data_color = lv_barcode_get_bg_color(obj);
if(barcode->have_update != true)
{
barcode->data_color = new_color;
return ;
}
lv_color_t *img_buf = (lv_color_t *)dsc->data;
for (int i = 0; i < dsc->header.w * dsc->header.h; i++)
{
if( memcmp(&img_buf[i], &data_color, sizeof(lv_color_t)) == false)
img_buf[i] = new_color;
}
barcode->data_color = new_color;
lv_img_set_src(img, dsc);
}
/*=====================
* Getter functions
*====================*/
lv_color_t lv_barcode_get_bg_color(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_barcode_t * barcode = (lv_barcode_t *)obj;
return barcode->bg_color;
}
lv_color_t lv_barcode_get_data_color(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_barcode_t * barcode = (lv_barcode_t *)obj;
return barcode->data_color;
}
lv_obj_t * lv_barcode_get_img(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_barcode_t * barcode = (lv_barcode_t *)obj;
return barcode->barcode_img;
}
lv_img_dsc_t * lv_barcode_get_imgdsc(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_barcode_t * barcode = (lv_barcode_t *)obj;
return &barcode->dsc;
}
/*=====================
* Other functions
*====================*/
/**********************
* STATIC FUNCTIONS
**********************/
static void generate_barcode_image(lv_obj_t * obj, const char *data, uint32_t width, uint32_t height)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_img_dsc_t * img_dsc = lv_barcode_get_imgdsc(obj);
lv_obj_t * img = lv_barcode_get_img(obj);
lv_color_t bg_color = lv_barcode_get_bg_color(obj);
lv_color_t data_color = lv_barcode_get_data_color(obj);
size_t estimated_length = code128_estimate_len(data);
LV_LOG_USER("estimated_length :%d\n", estimated_length);
char *barcode_data = (char *)lv_mem_alloc(estimated_length);
if(barcode_data == NULL)
{
LV_LOG_USER("lv_mem_alloc barcode_data err\n");
return NULL;
}
size_t actual_length = code128_encode_raw(data, barcode_data, estimated_length);
int min_width = actual_length * 2;
if (width < min_width) {
width = min_width;
}
LV_LOG_USER("img_buf len :%d\n", width * height * sizeof(lv_color_t));
lv_color_t *img_buf = (lv_color_t *)lv_mem_alloc(width * height * sizeof(lv_color_t));
if(img_buf == NULL)
{
LV_LOG_USER("lv_mem_alloc img_buf err\n");
return NULL;
}
for (int i = 0; i < width * height; i++) {
img_buf[i] = bg_color;
}
int unit_width = width / actual_length;
int remaining_width = width % actual_length;
int left_padding = (width - (actual_length * unit_width + remaining_width)) / 2;
int x = left_padding;
for (size_t i = 0; i < actual_length; i++) {
lv_color_t color = barcode_data[i] ? data_color : bg_color;
int bar_width = unit_width + (remaining_width > 0 ? 1 : 0);
if (remaining_width > 0) {
remaining_width--;
}
for (int j = 0; j < bar_width; j++) {
for (int k = 0; k < height; k++) {
img_buf[k * width + x + j] = color;
}
}
x += bar_width;
}
lv_mem_free(barcode_data);
img_dsc->header.always_zero = 0;
img_dsc->header.w = width;
img_dsc->header.h = height;
img_dsc->header.cf = LV_IMG_CF_TRUE_COLOR;
img_dsc->data_size = width * height * sizeof(lv_color_t);
img_dsc->data = (const uint8_t *)img_buf;
lv_img_set_src(img, img_dsc);
}
static void lv_barcode_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{
LV_UNUSED(class_p);
LV_TRACE_OBJ_CREATE("barcode begin");
lv_barcode_t * barcode = (lv_barcode_t *)obj;
/*set barcode bg style*/
barcode->barcode_bg = lv_obj_create(obj);
lv_obj_set_scroll_dir(barcode->barcode_bg, LV_DIR_NONE);
//lv_obj_set_size(barcode->barcode_bg, LV_HOR_RES/2, LV_HOR_RES/6);
lv_obj_remove_style(barcode->barcode_bg, NULL, LV_PART_SCROLLBAR);
lv_obj_set_style_bg_color(barcode->barcode_bg, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_radius(barcode->barcode_bg, LV_BARCODE_ARDIUS_LEN, LV_PART_MAIN);
lv_obj_align(barcode->barcode_bg, LV_ALIGN_CENTER, 0, 0);
/*create a barcode img*/
barcode->barcode_img = lv_img_create(barcode->barcode_bg);
//lv_img_set_src(barcode->barcode_img, NULL);
lv_obj_center(barcode->barcode_img);
/*set barcode color*/
barcode->bg_color = lv_color_white();
barcode->data_color = lv_color_black();
/*have not alloc data*/
barcode->have_update = false;
LV_TRACE_OBJ_CREATE("barcode finished");
}
static void lv_barcode_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{
LV_UNUSED(class_p);
lv_barcode_t * barcode = (lv_barcode_t *)obj;
if(barcode->have_update == true)
{
lv_mem_free(barcode->dsc.data);
barcode->have_update = false;
}
}
#endif /*LV_USE_BARCODE*/
lv_barcode.h
/**
* @file lv_barcode.h
*
*/
#ifndef LV_BARCODE_H
#define LV_BARCODE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_demos.h"
#if LV_USE_BARCODE != 0
/*********************
* DEFINES
*********************/
#define LV_BARCODE_ARDIUS_LEN (10)
#define LV_BARCODE_OBJ_WIDE (400)
#define LV_BARCODE_OBJ_HIDE (150)
/**********************
* TYPEDEFS
**********************/
/*Data of canvas*/
typedef struct {
lv_obj_t obj;
lv_obj_t * barcode_bg;
lv_obj_t * barcode_img;
lv_img_dsc_t dsc;
lv_color_t bg_color;
lv_color_t data_color;
bool have_update;
} lv_barcode_t;
/***********************
* GLOBAL VARIABLES
***********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Create an empty barcode (an `img`) object.
* @param parent point to an object where to create the barcode
* @return pointer to the created barcode object
*/
lv_obj_t * lv_barcode_create(lv_obj_t * parent);
/**
* Set the data of a barcode object
* @param barcode pointer to barcode object
* @param data data to display
* @param width barcode width
* @param height barcode height
*/
void lv_barcode_update(lv_obj_t * obj, const char *data, uint32_t width, uint32_t height);
/*=====================
* Setter functions
*====================*/
/**
* Get the calc btnmatrix to allow styling or other modifications
* @param obj pointer to a calc object
* @return pointer to the btnmatrix of the calc
*/
void lv_barcode_set_bg_color(lv_obj_t * obj, lv_color_t new_color);
/**
* Get the calc textarea(calc history) to allow styling or other modifications
* @param obj pointer to a calc object
* @return pointer to the textarea(calc history) of the calc
*/
void lv_barcode_set_data_color(lv_obj_t * obj, lv_color_t new_color);
/*=====================
* Getter functions
*====================*/
/**
* Get the barcode bgcolor
* @param obj pointer to a barcode object
* @return color barcode bgcolor
*/
lv_color_t lv_barcode_get_bg_color(lv_obj_t * obj);
/**
* Get the barcode data color
* @param obj pointer to a barcode object
* @return color barcode data color
*/
lv_color_t lv_barcode_get_data_color(lv_obj_t * obj);
/**
* Get the barcode data color
* @param obj pointer to a barcode object
* @return pointer to img object in barcode object
*/
lv_obj_t * lv_barcode_get_img(lv_obj_t * obj);
/**
* Get the barcode data color
* @param obj pointer to a barcode object
* @return pointer to img data in barcode
*/
lv_img_dsc_t * lv_barcode_get_imgdsc(lv_obj_t * obj);
/*=====================
* Static functions
*====================*/
static void generate_barcode_image(lv_obj_t * obj, const char *data, uint32_t width, uint32_t height);
static void lv_barcode_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static void lv_barcode_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
/**********************
* MACROS
**********************/
#endif /*LV_USE_100ASK_CALC*/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_USE_BARCODE*/
三、运行demo
void lv_demo_test(void)
{
lv_obj_t * bg = lv_obj_create(lv_scr_act());
lv_obj_set_size(bg, 466, 466);
lv_obj_set_scroll_dir(bg, LV_DIR_NONE);
lv_obj_remove_style(bg, NULL, LV_PART_SCROLLBAR);
lv_obj_set_style_bg_color(bg, lv_color_black(), LV_PART_MAIN);
lv_obj_t * barcode = lv_barcode_create(bg);
lv_barcode_update(barcode, "https://lvgl.io", 300, 100);
}