LVGL自定义组件__页面指示器

前言

LVGL对硬件的要求非常低,使用其自带的组件能够搭建出精美的界面,动效也很棒。但是如过移植到Linux平台下,开发稍微复杂的应用项目,那些组件就远远不够用了。为此需要自己自定义一些组件,以方便实用。

效果

为此,尝试开发了一个页面指示器,先看效果:
LVGL自定义组件__页面指示器_第1张图片

代码

Talk is cheap, show me your code.

circles.h

#include "lvgl.h"
#define MAX_INDEX 10
typedef struct circles_ {
    int max_index;
    int active_index;
    lv_style_t *active_style;
    lv_style_t *inactive_style;
    lv_obj_t *circle_list[MAX_INDEX];
    lv_obj_t *parent;
    int (*click_callback)(void);

    const char * name;
    void (*init)(void);
} circles_t;

typedef struct callback_user_data_{
    circles_t *circles;
    int index;
}callback_user_data_t;

// set the active index
int lv_circles_set_active_index(circles_t *circles, int index);
// draw the circles on the screen
int lv_draw_circles(circles_t *circles);

//demo function

void custom_components_circles_demo();

circles.c

#include "circles.h"

// usage:
// 1. define the callback function
void test_cb(lv_event_t *e){

    printf("hello world\n");
}


// 2.init the circles like this: 
void custom_components_circles_demo(){
    static lv_style_t inactive_style;
    lv_style_init(&inactive_style);
    lv_style_set_radius(&inactive_style,5);
    lv_style_set_size(&inactive_style, 10);
    lv_style_set_bg_color(&inactive_style,lv_palette_main(LV_PALETTE_GREY));
    lv_style_set_bg_opa(&inactive_style, 255);
    lv_style_set_text_opa(&inactive_style, 0);

    static lv_style_t active_style;
    lv_style_init(&active_style);
    lv_style_set_radius(&active_style,5);
    // lv_style_set_size(&active_style, 10);
    lv_style_set_width(&active_style, 20);
    lv_style_set_height(&active_style, 10);
    lv_style_set_bg_color(&active_style,lv_palette_main(LV_PALETTE_BLUE));
    lv_style_set_bg_opa(&active_style, 255);
    lv_style_set_text_opa(&active_style, 0);

    circles_t *circles;
    circles = (circles_t *)malloc(sizeof(circles_t));
    circles->active_style = &active_style;
    circles->inactive_style = &inactive_style;

    circles->max_index = 3;
    circles->active_index = 0;
    circles->name = "circles";
    circles->parent = lv_obj_create(lv_scr_act());

    lv_obj_set_size(circles->parent, 300, 75);
    lv_obj_set_flex_flow(circles->parent, LV_FLEX_FLOW_ROW);
    lv_obj_align(circles->parent,  LV_ALIGN_TOP_MID, 0, 5);

    circles->click_callback = test_cb;
    lv_draw_circles(circles);

}

int lv_circles_set_active_index(circles_t *circles, int index){
    if(index < 0 || index > circles->max_index) return -1;
    lv_obj_remove_style_all(circles->circle_list[circles->active_index]);
    lv_obj_remove_style_all(circles->circle_list[index]);
    lv_obj_add_style(circles->circle_list[circles->active_index], circles->inactive_style,0);
    lv_obj_add_style(circles->circle_list[index], circles->active_style,0);

    circles->active_index = index;
    return 0;
}
void lv_circles_event_cb(lv_event_t *e){
    callback_user_data_t *user_data = lv_event_get_user_data(e);
    lv_obj_t * btn = lv_event_get_target(e);
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_CLICKED){
        lv_circles_set_active_index(user_data->circles, user_data->index);
        if(user_data->circles->click_callback != NULL){
            user_data->circles->click_callback();
        }
    }
}
int lv_draw_circles(circles_t *circles){
    int i = 0;
    for(i =0;i<circles->max_index;i++){
        circles->circle_list[i] = lv_btn_create(circles->parent);
        lv_obj_remove_style_all(circles->circle_list[i]);
        callback_user_data_t *data = malloc(sizeof(callback_user_data_t));
        data->circles = circles;
        data->index = i;
        lv_obj_add_event_cb(circles->circle_list[i], lv_circles_event_cb, LV_EVENT_ALL, data);        
        if(i==circles->active_index){
            lv_obj_add_style(circles->circle_list[i], circles->active_style,0);
        }
        else{
            lv_obj_add_style(circles->circle_list[i], circles->inactive_style,0);
        }
    }
}

使用方法

  1. 项目根目录下,新建文件夹components,把上面的两个文件放进去
  2. 修改makefile
INC  := -I./ui/simulator/inc/ -I./ -I./lvgl/ -I ./components
  1. 要使用时引入头文件
#include "circles.h"
  1. 可以使用自带的Demo快速预览,具体使用方法可以参考Demo函数
custom_components_circles_demo();

配置

参考demo函数初始化配置即可:

  1. 建立点击回调函数,并注册到组件中,在指示器被点击后翻页使用
  2. 初始化active_style,inactive_style,设置自己需要的指示器样式
  3. 创建circles对象,初始化页面总个数和默认激活哪个页面
  4. 画到界面上

总结

由于刚刚上手lvgl,所以这个组件并没有完全基于lvgl中的基础对象lv_obj类型进行编写。感兴趣的同学可以参考官方组件的写法改写哦。

你可能感兴趣的:(C语言,lvgl,Linux,c++,开发语言)