当前位置:首页 > 公众号精选 > 漫长当下

在上篇文章中已经讲了源码实现,这篇文章将教会你怎么使用和移植到自己的项目中去,以此系列第一篇文章的效果视频为例,通过实例的方式展现其用法,快速上手。

还是先贴上代码:

#ifndef __M_GUI_TEST_H
#define __M_GUI_TEST_H

#define BUILD_TITLE(X,Y)                                             \
    {                                                                                       \
        if(!((*(X)).pszTitle))                                      \
        {                                                                                   \
            for(uint32_t i = 0;i < COUNTOF(X);i++)  \
            {                                                                               \
                (X)[i].pszTitle = (tTitle)&(Y)[i];      \
            }                                                                               \
        }                                                                                   \
    }


#endif/*__M_GUI_TEST_H*/

#include "./m_gui/m_gui.h"
#include "./m_gui/m_gui_test.h"
#include "./key_board/key_board.h"
#include "./oled.h"

static M_U32 key_up(void);
static M_U32 key_down(void);
static M_U32 key_left(void);
static M_U32 key_right(void);
static M_U32 key_enter(void);
static M_U32 key_exit(void);

MENU_GUI gui;

opsTypeDef ops = {
    .pset = (void (*)(M_U16, M_U16, M_U8))OLED_DrawPoint,
    .pclear = (void (*)(void))OLED_clcScreen,
    .pputString = (void (*)(M_U16, M_U16, M_U8, void *))OLED_INT_CharDisp,
};

keyTypeDef key = {
    .up = key_up,
    .down = key_down,
    .left = key_left,
    .right = key_right,
    .enter = key_enter,
    .exit = key_exit,
};

//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
static  void page_item1_S_f(void);

static const struct sTitle page_item1_o_t[] = {
{"speed-10",40,16},
{"speed-20",40,96},
{"speed-30",40,176},
};
static const struct sItem page_item1_o[] = {
{(tTitle)&page_item1_o_t[0],NULL},
{(tTitle)&page_item1_o_t[1],NULL},
{(tTitle)&page_item1_o_t[2],NULL},
};
static const struct sTitle page_item1_t[] = {"速度选择",0,0};
static struct sMenu page_item1[] = {(tTitle)page_item1_t,(tItem)page_item1_o,COUNTOF(page_item1_o),0,1,3,(thmi)hmi_def,page_item1_S_f};

static void page_item1_S_f(void)
{
  gui_put_string(10, OLED_Y_COR_CENTER(strlen(gui.active->pszTitle->str)), 0, gui.active->pszTitle->str);
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
static  void page_item2_S_f(void);

static const struct sTitle page_item2_o_t[] = {
{"选项1",29,40},
};
static struct sItem page_item2_o[] = {
{NULL,page_item1},
};
static const struct sTitle page_item2_t[] = {"菜单3",0,0};
static struct sMenu page_item2[] = {(tTitle)page_item2_t,(tItem)page_item2_o,COUNTOF(page_item2_o),0,1,3,(thmi)hmi_def,page_item2_S_f};

static void page_item2_S_f(void)
{
    BUILD_TITLE(page_item2_o,page_item2_o_t)

  gui_put_string(10, OLED_Y_COR_CENTER(strlen(gui.active->pszTitle->str)), 0, gui.active->pszTitle->str);
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
static  void page_item3_S_f(void);

static struct sMenu page_item3[] = {(tTitle)NULL,(tItem)NULL,0,0,0,0,(thmi)hmi_def,page_item3_S_f};

static void page_item3_S_f(void)
{
  char tmpStr[32] = {0};

  sprintf(tmpStr,"%s","测试test");

  gui_put_string(10, OLED_Y_COR_CENTER(strlen(tmpStr)), 0, tmpStr);
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
static  void page_item4_S_f(void);

static const struct sTitle page_item4_o_t[] = {
{"选项1",29,40},
{"选项2",29,152},
{"选项3",48,40},
};
static struct sItem page_item4_o[] = {
{NULL,page_item1},
{NULL,page_item2},
{NULL,page_item3},
};
static const struct sTitle page_item4_t[] = {"菜单2",0,0};
static struct sMenu page_item4[] = {(tTitle)page_item4_t,(tItem)page_item4_o,COUNTOF(page_item4_o),0,1,3,(thmi)hmi_def,page_item4_S_f};

static void page_item4_S_f(void)
{
    BUILD_TITLE(page_item4_o,page_item4_o_t)

  gui_put_string(10, OLED_Y_COR_CENTER(strlen(gui.active->pszTitle->str)), 0, gui.active->pszTitle->str);
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
static  void page_item5_S_f(void);

static const struct sTitle page_item5_o_t[] = {
{"speed-10",40,16},
{"speed-20",40,96},
{"speed-30",40,176},
};
static const struct sItem page_item5_o[] = {
{(tTitle)&page_item5_o_t[0],NULL},
{(tTitle)&page_item5_o_t[1],NULL},
{(tTitle)&page_item5_o_t[2],NULL},
};
static const struct sTitle page_item5_t[] = {"速度选择",0,0};
static struct sMenu page_item5[] = {(tTitle)page_item5_t,(tItem)page_item5_o,COUNTOF(page_item5_o),0,1,3,(thmi)hmi_def,page_item5_S_f};

static void page_item5_S_f(void)
{
  gui_put_string(10, OLED_Y_COR_CENTER(strlen(gui.active->pszTitle->str)), 0, gui.active->pszTitle->str);
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
static void pageS_f(void);//主界面

static const struct sTitle page_o_t[] = {
{"选项1",29,40},
{"选项2",29,152},
{"选项3",48,40},
{"选项4",48,152},
{"选项5",29,40},
};
static struct sItem page_o[] = {
{NULL,page_item1},
{NULL,page_item2},
{NULL,page_item3},
{NULL,page_item4},
{NULL,page_item5},
};
static const struct sTitle page_t[] = {"菜单1",0,0};
static struct sMenu page[] = {(tTitle)page_t,(tItem)page_o,COUNTOF(page_o),0,2,2,(thmi)hmi_def,pageS_f};

static void pageS_f(void)
{
    BUILD_TITLE(page_o,page_o_t)

    gui_put_string(10, OLED_Y_COR_CENTER(strlen(gui.active->pszTitle->str)), 0, gui.active->pszTitle->str);
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//

void gui_test(void)
{
    gui_init(&gui,&ops,&key);
    gui_select(&gui);
    gui_set_active(page);
    gui_send_sig(gui.active);
}

M_U32 key_up(void)
{
    return (KeyGetState(KEY_UP) == KEY_RELEASE);
}

M_U32 key_down(void)
{
    return (KeyGetState(KEY_DOWN) == KEY_RELEASE);
}

M_U32 key_left(void)
{
    return (KeyGetState(KEY_LEFT) == KEY_RELEASE);
}

M_U32 key_right(void)
{
    return (KeyGetState(KEY_RIGHT) == KEY_RELEASE);
}

M_U32 key_enter(void)
{
    return (KeyGetState(KEY_ENTER) == KEY_RELEASE);
}

M_U32 key_exit(void)
{
    return (KeyGetState(KEY_EXIT) == KEY_RELEASE);
}

/*
使用示例(一个任务或者定时器)
void gui_task(void)
{
    M_U32 tmpCnt = 0; gui_test();//初始化

    for(;;)
    {
        //按键每10ms扫描一次
        if(0 == (tmpCnt++ % 10))
        {
            //你的键盘扫描
            do something

            //响应按键后的具体操作
            gui_key_scan();
        }

        //有事件时更新
        gui_flush();

        //1ms调度
        vTaskDelay(1);
    }
}

//目前键盘仅实现了菜单项的选择,菜单的切换功能,如果想实现数值修改等其它功能,只需要新增相应的键盘操作即可,可参考hmi_def的实现
*/

通过以上代码就实现了此系列第一篇文章的效果,可以看到,每一个菜单都是一个小部分,可以随意的增删改,而不会影响其它的菜单,更不用改了一个菜单后还需要重新构建菜单层级关系,使用和维护都是非常方便的。

总结:这个小项目虽然简单,但是在合适的场景其发挥的作用可以说是举足轻重的 ,从最开始的上千行代码,到现在的几百行代码就能完成的功能,对我来说也是一种进步,经过好几版的改进,重构,才有了现在的效果,我不能说这已经是最好的,但可以说是目前更好的,希望我的思路能给你带来启发。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭