日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > > 大橙子瘋嵌入式


前言

作為嵌入式軟件開發(fā),可能經(jīng)常會使用命令行或者顯示屏等設(shè)備實現(xiàn)人機(jī)交互的功能,功能中通常情況都包含 UI 菜單設(shè)計;對于復(fù)雜的UI設(shè)計,可能最多優(yōu)先考慮的是使用開源的GUI庫。
但是GUI使用起來復(fù)雜,在簡單的UI設(shè)計中則臃腫或者較難實現(xiàn)(比如OLED這種);基于這種情況,很多開發(fā)人員都會有自己的菜單框架模塊,避免重復(fù)造輪子,網(wǎng)上有很多這種菜單框架的代碼,但是大多耦合性太強(qiáng)。

代碼層面上大部分都耦合了按鍵和不同平臺(不同尺寸的OLED)等模塊;并無法獨立出來適配不同的菜單設(shè)計。
而多級菜單的設(shè)計也使得上層軟件被迫耦合,比如一張表包含了多級菜單內(nèi)容等。

基于以上種種痛點,本文介紹一個耦合性低,完全可移植的輕量級菜單框架,菜單顯示風(fēng)格和顯示平臺完全由自己根據(jù)需求設(shè)計,而菜單操作統(tǒng)一由菜單框架處理即可,提高程序的移植性。

特點

主要特點就是耦合性低,移植無需修改。且不和任何模塊耦合,同時對于上層軟件設(shè)計,也可以做到解耦實現(xiàn)。

可以為不同菜單設(shè)計不同的顯示風(fēng)格。

介紹

多級菜單

同級菜單以數(shù)組的方式體現(xiàn),父菜單和子菜單的關(guān)聯(lián)則使用鏈表實現(xiàn)。

數(shù)組元素內(nèi)容有:

  • 菜單選項字符串描述(多語種可設(shè)置)

  • 菜單選項進(jìn)入回調(diào)函數(shù):當(dāng)前菜單選項進(jìn)入時(從父菜單進(jìn)入)需要執(zhí)行一次的函數(shù)

  • 菜單選項退出回調(diào)函數(shù):當(dāng)前菜單選項進(jìn)入后退出時(退出至父菜單)需要執(zhí)行一次的函數(shù)

  • 菜單選項重加載回調(diào)函數(shù):當(dāng)前菜單選項每次加載時(從父菜單進(jìn)入或子菜單退出)需要執(zhí)行一次的函數(shù)

  • 菜單選項周期調(diào)度回調(diào)函數(shù):當(dāng)前菜單選項的周期調(diào)度函數(shù)

  • 菜單選項的擴(kuò)展數(shù)據(jù)

鏈表內(nèi)存可以選擇采用動態(tài)內(nèi)存分配或者數(shù)組實現(xiàn)

方便對不同菜單界面功能解耦

大部分菜單采用的都是數(shù)組中包含了所有不同級別的菜單選項內(nèi)容實現(xiàn),無法做到很好的解耦方式;

該模塊通過動態(tài)綁定子菜單和鏈表的方式可以達(dá)到較好的解耦狀態(tài)

顯示效果

該框架只負(fù)責(zé)菜單選項控制操作,不負(fù)責(zé)在圖像界面顯示效果,需要在對應(yīng)的回調(diào)函數(shù)中實現(xiàn)菜單顯示效果。

設(shè)置對應(yīng)的效果顯示函數(shù),即可為不同的菜單設(shè)置不同的菜單顯示效果,比如圖標(biāo)式、列表式或右側(cè)彈窗式等。

可以在不同顯示平臺體現(xiàn),比如LCD、OLED或終端界面等。

可擴(kuò)展

每級菜單選項都可以設(shè)置自定義數(shù)據(jù),用來實現(xiàn)更多的菜單操作或者顯示效果等。

不同級別的菜單可以設(shè)置自定義數(shù)據(jù)(比如菜單選項隱藏/圖標(biāo)數(shù)據(jù)等)

可配置

配置選項 描述
_COT_MENU_USE_MALLOC_ 定義則采用 malloc/free 的方式實現(xiàn)多級菜單, 否則通過數(shù)組的形式
_COT_MENU_USE_SHORTCUT_ 定義則啟用快捷菜單選項進(jìn)入功能
COT_MENU_MAX_DEPTH 多級菜單深度
COT_MENU_MAX_NUM 菜單支持的最大選項數(shù)目
COT_MENU_SUPPORT_LANGUAGE 菜單支持的語種數(shù)目

功能多樣化

    多語種。

  • 支持菜單選項多語種切換,至少設(shè)置一種語言

  • 多語種除了該方式,還可以使用多語種配置數(shù)據(jù)實現(xiàn),比如鍵值對,鍵作為菜單選項字符串體現(xiàn)

    支持快速進(jìn)入指定菜單界面。

  • 可以通過相對選項索引或者絕對選項索引路徑實現(xiàn)

    可以實現(xiàn)有限界面內(nèi)顯示少量的菜單選項內(nèi)容。

  • 有現(xiàn)成的函數(shù)可用,無需擔(dān)心使用不同尺寸重新實現(xiàn)菜單選項部分可見

使用說明

菜單初始化和使用

// 定義菜單信息,函數(shù)由主菜單模塊定義并提供static cotMainMenuCfg_t sg_tMainMenu = {{"主菜單", "Main Menu"}, Hmi_EnterMainHmi, NULL, NULL, NULL}; int main(void){ cotMenu_Init(&sg_tMainMenu);  while (1) { ...  if (timeFlag) { timeFlag = 0; cotMenu_Task(); // 周期調(diào)度 } }}
 

主菜單定義和綁定

定義一個主菜單選項內(nèi)容、主菜單顯示效果函數(shù)和主菜單進(jìn)入函數(shù)等

// 擴(kuò)展數(shù)據(jù)為圖標(biāo)文件名字cotMenuList_t sg_MainMenuTable[] = { {{"音樂", "Music"},  Hmi_MusicEnter, Hmi_MusicExit, Hmi_MusicLoad, Hmi_MusicTask, "music"}, {{"視頻", "Video"}, NULL, Hmi_VideoExit, Hmi_VideoLoad, Hmi_VideoTask, "video"}, {{"攝像機(jī)", "Camera"},  Hmi_CameraEnter, Hmi_CameraExit, Hmi_CameraLoad, Hmi_CameraTask, "camera"}, {{"設(shè)置", "Setting"}, Hmi_SetEnter, Hmi_SetExit, Hmi_SetLoad,   Hmi_SetTask, "setting"},}; /* 主菜單顯示效果 */static void ShowMainMenu(cotMenuShow_t *ptShowInfo){ char *pszSelectDesc = ptShowInfo->pszItemsDesc[ptShowInfo->selectItem]; oledsize_t idx = (128 - 6 * strlen(pszSelectDesc)) / 2;  cotOled_DrawGraphic(40, 0, (const char *)ptShowInfo->pItemsExData[ptShowInfo->selectItem], 1);  cotOled_SetText(0, 50, "                ", 0, FONT_12X12); cotOled_SetText(idx, 50, pszSelectDesc, 0, FONT_12X12);} void Hmi_EnterMainHmi(void){ cotMenu_Bind(sg_MainMenuTable, COT_GET_MENU_NUM(sg_MainMenuTable), ShowMainMenu);} 

子菜單定義和綁定

如果菜單選項有子菜單,則該菜單選項調(diào)用cotMenu_Enter,進(jìn)入回調(diào)函數(shù)不能為NULL,且該回調(diào)函數(shù)需調(diào)用cotMenu_Bind進(jìn)行綁定

/* 設(shè)置的子菜單內(nèi)容 */cotMenuList_t sg_SetMenuTable[] = { {{"語言", "Language"}, NULL, NULL, NULL, OnLanguageFunction, NULL}, {{"藍(lán)牙", "Bluetooth"}, NULL, NULL, NULL, OnBluetoothFunction, NULL}, {{"電池", "Battery"}, NULL, NULL, NULL, OnBatteryFunction, NULL}, {{"儲存", "Store"}, NULL, NULL, NULL, OnStorageFunction, NULL}, {{"更多", "More"},       Hmi_MoreSetEnter, Hmi_MoreSetExit, Hmi_MoreSetLoad, Hmi_MoreSetTask, NULL},}; /* 設(shè)置菜單顯示效果 */static void ShowSetMenu(cotMenuShow_t *ptShowInfo){ uint8_t showNum = 3; menusize_t tmpselect;  cotMenu_LimitShowListNum(ptShowInfo, &showNum);  printf("\e[0;30;46m ------------- %s ------------- \e[0m\n", ptShowInfo->pszDesc);  for (int i = 0; i < showNum; i++) { tmpselect = i + ptShowInfo->showBaseItem;  if (tmpselect == ptShowInfo->selectItem) { printf("\e[0;30;47m %d. %-16s\e[0m |\n", tmpselect + 1, ptShowInfo->pszItemsDesc[tmpselect]); } else { printf("\e[7;30;47m %d. %-16s\e[0m |\n", tmpselect + 1, ptShowInfo->pszItemsDesc[tmpselect]); } }} void Hmi_SetEnter(void){ // 進(jìn)入設(shè)置選項后綁定子菜單,同時為當(dāng)前綁定的菜單設(shè)置顯示效果函數(shù) cotMenu_Bind(sg_SetMenuTable, COT_GET_MENU_NUM(sg_SetMenuTable), ShowSetMenu); } 

菜單控制

通過調(diào)用相關(guān)函數(shù)實現(xiàn)菜單選項選擇、進(jìn)入、退出等

// 需要先進(jìn)入主菜單cotMenu_MainEnter(); // 選擇上一個,支持循環(huán)選擇(即第一個可跳轉(zhuǎn)到最后一個)cotMenu_SelectPrevious(true); // 選擇下一個,不支持循環(huán)選擇(即最后一個不可跳轉(zhuǎn)到第一個)cotMenu_SelectNext(false); // 進(jìn)入,會執(zhí)行菜單選項的 pfnEnterCallFun 回調(diào)函數(shù)cotMenu_Enter(); // 退出,會執(zhí)行父菜單該選項的 pfnExitCallFun 回調(diào)函數(shù),并在退出后父菜單選項列表復(fù)位從頭選擇cotMenu_Exit(true);

Demo顯示效果

示例代碼采用的平臺是命令行輸出輸入顯示效果

demo中提供了如何實現(xiàn)圖形菜單(主菜單有點粗糙)、普通列表菜單、右側(cè)彈窗菜單(更多設(shè)置)等效果演示,菜單樣式可自由擴(kuò)展,足夠自由;快捷菜單操作、中英文切換演示。(windows中編譯需要將 demo.c轉(zhuǎn) GBK 編碼,Linux 轉(zhuǎn) utf8 編碼,不然可能出現(xiàn)漢字亂碼的問題)

以下是通過單片機(jī)驅(qū)動 OLED 顯示的菜單界面顯示效果

下載鏈接

下載鏈接(點擊閱讀原文),或更新內(nèi)容可看:

https://gitee.com/cot_package/cot_menu


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉