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

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


前言

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

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

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

特點(diǎn)

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

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

介紹

多級(jí)菜單

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

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

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

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

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

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

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

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

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

方便對(duì)不同菜單界面功能解耦

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

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

顯示效果

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

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

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

可擴(kuò)展

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

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

可配置

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

功能多樣化

    多語種。

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

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

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

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

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

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

使用說明

菜單初始化和使用

// 定義菜單信息,函數(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)度 } }}
 

主菜單定義和綁定

定義一個(gè)主菜單選項(xiàng)內(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);} 

子菜單定義和綁定

如果菜單選項(xiàng)有子菜單,則該菜單選項(xiàng)調(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}, {{"儲(chǔ)存", "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è)置選項(xiàng)后綁定子菜單,同時(shí)為當(dāng)前綁定的菜單設(shè)置顯示效果函數(shù) cotMenu_Bind(sg_SetMenuTable, COT_GET_MENU_NUM(sg_SetMenuTable), ShowSetMenu); } 

菜單控制

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

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

Demo顯示效果

示例代碼采用的平臺(tái)是命令行輸出輸入顯示效果

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

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

下載鏈接

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

https://gitee.com/cot_package/cot_menu


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