LVGL:绘制一个自定义按钮的例子

#ifndef LV_PUSHBUTTON_T_H
#define LV_PUSHBUTTON_T_H

#include "lvgl/lvgl.h"
#include <string>

typedef struct
{
    lv_obj_t obj;
    lv_style_t style;
    bool pressed;
    lv_color_t backgroundColor;
    std::string text;
}lv_pushbutton_t;

extern const lv_obj_class_t lv_pushbutton_class;

lv_obj_t * lv_pushbutton_create(lv_obj_t * parent);
void lv_pushbutton_set_text(lv_obj_t * obj,const char * text);

#endif // LV_PUSHBUTTON_T_H
#include "lv_pushbutton_t.h"

#define MY_CLASS &lv_pushbutton_class

static void lv_pushbutton_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static void lv_pushbutton_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static void lv_pushbutton_event(const lv_obj_class_t * class_p, lv_event_t * e);

LV_FONT_DECLARE(lv_font_siyuanheiti16) //注册字体

const lv_obj_class_t lv_pushbutton_class =
{
    .base_class = &lv_obj_class,
    .constructor_cb = lv_pushbutton_constructor,
    .destructor_cb = lv_pushbutton_destructor,
    .event_cb = lv_pushbutton_event,
    .width_def = LV_SIZE_CONTENT,
    .height_def = LV_SIZE_CONTENT,
    .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE,
    .instance_size = sizeof(lv_pushbutton_t)
};

lv_obj_t * lv_pushbutton_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);

    lv_pushbutton_t * btn = (lv_pushbutton_t*)obj;
    btn->pressed = false;
    btn->text = "确定";

    auto & style = btn->style;
    lv_style_init(&style);
    lv_style_set_bg_opa(&style, LV_OPA_COVER);//必不可少,否则默认控件背景不可见

    lv_style_set_bg_color(&style,lv_color_hex(0xe8e8e8));
    lv_style_set_text_font(&style,&lv_font_siyuanheiti16);
    lv_style_set_radius(&style, 12);
    lv_style_set_border_width(&style,10);
    lv_style_set_border_color(&style,lv_color_hex(0x33dd33));
    lv_style_set_border_opa(&style,LV_OPA_50);

    lv_obj_add_style(obj, &style, LV_PART_MAIN);

    return obj;
}

static void lv_pushbutton_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{
    LV_UNUSED(class_p);
    LV_TRACE_OBJ_CREATE("begin");

    LV_TRACE_OBJ_CREATE("finished");
}

static void lv_pushbutton_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{
    LV_UNUSED(class_p);
    LV_TRACE_OBJ_CREATE("begin");

    LV_TRACE_OBJ_CREATE("finished");
}

static void lv_pushbutton_event(const lv_obj_class_t * class_p, lv_event_t * e)
{
    LV_UNUSED(class_p);

    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_REFR_EXT_DRAW_SIZE) {
        lv_coord_t * s = (lv_coord_t *)lv_event_get_param(e);
        *s = LV_MAX(*s, 20);
    }
    else if(code == LV_EVENT_DRAW_MAIN)
    {
        lv_pushbutton_t * btn = (lv_pushbutton_t*)obj;

        lv_draw_rect_dsc_t rect_dsc;
        lv_draw_rect_dsc_init(&rect_dsc);
        lv_obj_init_draw_rect_dsc(obj, LV_PART_MAIN, &rect_dsc);//用obj的 LV_PART_MAIN 样式属性初始化 rect_dsc

        if(btn->pressed)
        {
            rect_dsc.bg_color = lv_color_mix(rect_dsc.bg_color, lv_color_black(), 200);
        }

        const lv_area_t * clip_area = (const lv_area_t *)lv_event_get_param(e);

        const auto & area = obj->coords;

        lv_obj_draw_part_dsc_t  part_draw_dsc;
        lv_obj_draw_dsc_init(&part_draw_dsc, clip_area);
        part_draw_dsc.class_p =  &lv_obj_class;
        part_draw_dsc.rect_dsc = &rect_dsc;
        part_draw_dsc.part = LV_PART_MAIN;

        lv_draw_rect(&area, clip_area, &rect_dsc);

        const char * text = btn->text.c_str();

        lv_point_t txt_size;
        lv_txt_get_size(&txt_size, text,
                        lv_obj_get_style_text_font(obj, LV_PART_MAIN),
                        lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN),
                        0,
                        LV_COORD_MAX, LV_TEXT_FLAG_NONE);

        lv_area_t txt_coords;
        txt_coords.x1 = area.x1 + (area.x2 - area.x1 - txt_size.x) / 2;
        txt_coords.y1 = area.y1 + (area.y2 - area.y1 - txt_size.y) / 2;
        txt_coords.x2 = txt_coords.x1 + txt_size.x;
        txt_coords.y2 = txt_coords.y1 + txt_size.y;

        lv_draw_label_dsc_t label_dsc;
        lv_draw_label_dsc_init(&label_dsc);
        lv_obj_init_draw_label_dsc(obj, LV_PART_MAIN, &label_dsc);

        lv_draw_label(&txt_coords, clip_area, &label_dsc, text, NULL);
    }
    else if(code == LV_EVENT_PRESSED)
    {
        lv_pushbutton_t * btn = (lv_pushbutton_t*)obj;
        btn->pressed = true;
        lv_obj_invalidate(obj);
    }
    else if(code == LV_EVENT_RELEASED)
    {
        lv_pushbutton_t * btn = (lv_pushbutton_t*)obj;
        btn->pressed = false;
        lv_obj_invalidate(obj);
    }
}

void lv_pushbutton_set_text(lv_obj_t *obj, const char *text)
{
    LV_ASSERT_OBJ(obj, MY_CLASS);
    lv_pushbutton_t * btn = (lv_pushbutton_t*)obj;
    btn->text = text;
}

使用:

#include "lv_pushbutton_t.h"

int main(int argc, char **argv)
{
    lv_init();
    hal_init();

    lv_log_register_print_cb(esp32_log_cb);

    {
        lv_obj_t * obj = lv_pushbutton_create(lv_scr_act());
        lv_obj_set_size(obj, 200, 100);
        lv_obj_center(obj);
        lv_pushbutton_set_text(obj,"一个按钮");
    }

    while (1)
    {
        lv_timer_handler();
        usleep(5 * 1000);
    }

    return 0;
}

这仍可以使用样式配置:

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值