单色OLED屏可移植多级菜单式GUI(3)-使用

来源:漫长当下 嵌入式 21 次阅读
摘要:在上篇文章中已经讲了源码实现,这篇文章将教会你怎么使用和移植到自己的项目中去,以此系列第一篇文章的效果视频为例,通过实例的方式展现其用法,快速上手。 还是先贴上代码: `#ifndef __M_GUI_TEST_H define __M_GUI_TEST_H define BUILD_TITLE(X,Y)                                             \

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

还是先贴上代码:

`#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的实现 */ `

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

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

点击下面的链接查看系列其它文章:

单色OLED屏可移植多级菜单式GUI(1)-简介

单色OLED屏可移植多级菜单式GUI(2)-源码

相关推荐
评论区

登录后即可参与讨论

立即登录