落叶行健ywm的个人空间 https://bbs.21ic.com/?772247 [收藏] [复制] [RSS]

日志

我的菜单模板之菜单解析

热度 1已有 983 次阅读2015-5-12 09:05 |个人分类:嵌入式开发|系统分类:嵌入式系统| 菜单

上一篇我把主要的数据结构和菜单数组都列出来,这篇主要说明函数如何解析菜单数组来组织菜单形式的。
第一步:绘制单一菜单
//绘制某个菜单,参数是菜单位置
void uiProcMenu(u8 nPopupMenuTitle)
{
        u32 nCount, nTopIndex = 0, nCurrentIndex = 0;
        T_UI_MENUITEM *pUiStartMenuItem = &g_uiMenuItems[0], *pUiEndMenuItem;
        u8 nKey;
        uiProcMenuSettingStart(nPopupMenuTitle);
        //从第一个位置开始查找nPopupMenuTitle的位置
        while (pUiStartMenuItem->nMenuStr != nPopupMenuTitle ||
                (s32)pUiStartMenuItem->nType < 0)//这里可以解释为什么类型都是负值了
        {
                pUiStartMenuItem++;
        }
        pUiStartMenuItem++;//找到nPopupMenuTitle位置后,跳出来加1就是实际位置

        pUiEndMenuItem = pUiStartMenuItem;//结束位置从开始位置接着
        while ((s32)pUiEndMenuItem->nType < 0)//循环到下个菜单位置就是结束位置定位
        {
                pUiEndMenuItem++;
        }
        //计算这个menu下有多少个子菜单
        nCount = ((u32)pUiEndMenuItem - (u32)pUiStartMenuItem)/sizeof(T_UI_MENUITEM);
        //绘画菜单界面
        uiProcMenuDraw(pUiStartMenuItem, nCount, nTopIndex, nCurrentIndex);
        while(1)
        {
                vTaskDelay(100);
                if( (nKey = uiKeyGetKey()) == UIKEY_ESC)//自己根据实际情况去实现,各种模拟也行
                {
                        uiProcMenuSettingEnd(nPopupMenuTitle);
                        break;
                }
                switch(nKey) 
                {
                        case UIKEY_OK:
                                if (pUiStartMenuItem[nCurrentIndex].nType == UIMENU_POPUP)//处理有下拉菜单的选项
                                {
                                        uiProcMenu(pUiStartMenuItem[nCurrentIndex].nMenuStr);
                                }
                                else if(pUiStartMenuItem[nCurrentIndex].nType == UIMENU_HASVALUE)//有值改变的情况处理
                                {
                                        uiProcMenuHasValue(nPopupMenuTitle, &pUiStartMenuItem[nCurrentIndex], 
                                                1 + (nCurrentIndex - nTopIndex),nCurrentIndex);
                                }
                                else if (pUiStartMenuItem[nCurrentIndex].nType == UIMENU_CUSTOM)
                                {
                                        ///uiProcMenuCustom(nPopupMenuTitle, &pUiStartMenuItem[nCurrentIndex],1 + (nCurrentIndex - nTopIndex));
                                }
                                uiProcMenuDraw(pUiStartMenuItem, nCount, nTopIndex, nCurrentIndex);
                                break;
                        case UIKEY_UP:
                                if (nCurrentIndex > 0)
                                        nCurrentIndex --;
                                if (nCurrentIndex < nTopIndex)
                                        nTopIndex = nCurrentIndex;
                                uiProcMenuDraw(pUiStartMenuItem, nCount, nTopIndex, nCurrentIndex);
                                break;
                        case UIKEY_DOWN:
                                if (nCurrentIndex < nCount - 1)
                                        nCurrentIndex ++;
                                ///if (nCurrentIndex > nTopIndex + 2)
                                        ///nTopIndex = nCurrentIndex - 2;
                                if (nCurrentIndex > nTopIndex +  (MENU_OF_ITEMS-1))//这个值的设定和屏幕显示菜单数有关
                                        nTopIndex = nCurrentIndex -  (MENU_OF_ITEMS-1);
                                uiProcMenuDraw(pUiStartMenuItem, nCount, nTopIndex, nCurrentIndex);
                                break;
                        default:
                                break;
                }
        }
}

2:其他函数
//可用来过滤掉某些菜单不显示
void uiProcMenuSettingStart(u32 nPopupMenuTitle)
{

}
//这里主要用来最终判断每次退出一个菜单
//后是否有需要数据保存       
void uiProcMenuSettingEnd(u32 nPopupMenuTitle)
{
//内容自己实现
}
3:实现绘制各个菜单函数,至于实现某个功能的函数,那就是细致下去的活了,自己把握
////绘画菜单界面
void uiProcMenuDraw(T_UI_MENUITEM *pUiStartMenuItem, u32 nCount,u32 nTopIndex, u32 nCurrentIndex)
{
        u32 i, nIndex;
        u8 bSelected;
        //清除下界面
        //uiLcdClear();
        OLED_StartDraw();
        OLED_ClrScr(0);
        //显示菜单主题
        switch((pUiStartMenuItem-1)->nMenuStr)//找type对应的值
        {
                case UISTR_MENU:
                        Lcd_HZ_1212(UISTR_HZ_HBKJ,0, 3 ,4);
                        break;
                case UISTR_MENU_ONE:
                        ///uiLcd_1212_ch(UISTR_ZAIZHONG_SET_ZHONGLIANGZHILING, 0, 40, 2);
                        Lcd_HZ_1212(UISTR_HZ_HJLC,0, 3 ,4);
                        break;
                case UISTR_MENU_TWO:
                        //uiLcd_1212_ch(UISTR_PINGCHENG_SET, 0, 40, 4);
                        Lcd_HZ_1212(UISTR_HZ_ZL,0, 3 ,2);
                        break;
                case UISTR_MENU_THR:
                        //uiLcd_1212_ch(UISTR_ENCODER_FLOOR+2, 0, 40, 2);
                        break;
                default:
                        break;
        }
        for(i=0; i<MENU_OF_ITEMS; i++)//循环显示一个主题下的三个项目
        {
                nIndex = nTopIndex + i;
                if (nIndex >= nCount)
                        break;
                if (nIndex == nCurrentIndex)//区别显示当前选择的项目
                {
                        bSelected = TRUE;
                        Lcd_Decimal_Small(nCurrentIndex+1, (1+i)*12+4, 0, 1, 1);
                        Lcd_String_Small(">", (1+i)*12+4, 7,1);
                }
                else
                {
                        bSelected = FALSE;
                }
               
                //在这里添加菜单目录的绘画
                switch(pUiStartMenuItem[nIndex].nMenuStr)//找type对应的值
                {
                        //主菜单下的显示
                        case UISTR_MENU_ONE:
                                Lcd_HZ_1212(UISTR_HZ_HBKJ, 1+i, 1 ,1);
                                //uiLcd_1212_ch(UISTR_PINGCHENG_SET, (1+i)*2, HEAD_LEN, 4);
                                break;
                        case UISTR_MENU_TWO:
                                ///Lcd_HZ_1212(0,2, 1, 4);
                                Lcd_HZ_1212(UISTR_HZ_HBKJ+1, 1+i, 1 ,1);
                                //uiLcd_1212_ch(UISTR_ZAIZHONG_SET_ZHONGLIANGZHILING, (1+i)*2, HEAD_LEN, 2);
                                //uiLcd_1212_ch(UISTR_ZAIZHONG_SET+2, (1+i)*2, HEAD_LEN+12*2, 2);
                                break;
                        case UISTR_MENU_THR:
                                Lcd_HZ_1212(UISTR_HZ_HBKJ+2, 1+i, 1 ,1);
                                //uiLcd_1212_ch(UISTR_PINGCHENG_SET, (1+i)*2, HEAD_LEN, 4);
                                break;
                        case UISTR_MENU_FOU:
                                Lcd_HZ_1212(UISTR_HZ_HBKJ+3,1+i, 1 ,1);
                                //uiLcd_1212_ch(UISTR_PINGCHENG_SET, (1+i)*2, HEAD_LEN, 4);
                                break;
                               
                        //二级菜单下的显示
                        case UISTR_MENU_ONE_ONE:
                                Lcd_HZ_1212(UISTR_HZ_HJLC, 1+i, 1 ,1);
                                //uiLcd_1212_ch(UISTR_PINGCHENG_SET, (1+i)*2, HEAD_LEN, 4);
                                break;
                        case UISTR_MENU_ONE_TWO:
                                Lcd_HZ_1212(UISTR_HZ_HJLC+1, 1+i, 1 ,1);
                                //uiLcd_1212_ch(UISTR_PINGCHENG_SET, (1+i)*2, HEAD_LEN, 4);
                                break;
                        case UISTR_MENU_ONE_FOU:
                                Lcd_HZ_1212(UISTR_HZ_YJDBD, 1+i, 1 ,5);
                                //uiLcd_1212_ch(UISTR_PINGCHENG_SET, (1+i)*2, HEAD_LEN, 4);
                                break;
                        default:
                                //i = (pUiStartMenuItem-1)->nMenuStr;
                                break;
                }
                if (pUiStartMenuItem[nIndex].nType == UIMENU_HASVALUE ||
                        pUiStartMenuItem[nIndex].nType == UIMENU_CUSTOM_HASVALUE)
                {
                        uiProcMenuDrawValue(&pUiStartMenuItem[nIndex], (1+i)*12+4, bSelected);
                }
        }
        OLED_EndDraw();
}
4:实现有数值显示的,有下拉菜单的,有整个界面显示的功能。这些就是我们根据工程情况去自己实现的。
//画有值要显示的部分
void uiProcMenuDrawValue(T_UI_MENUITEM *pUiMenuItem, int row, u8 bIsReverse)
{
}
//处理有数值显示的
void uiProcMenuHasValue(int nPopupMenuTitle, T_UI_MENUITEM *pUiMenuItem, int row,int nCurrentIndex)
{
}
总结:嵌入式的很多界面处理机制可按照这个模式进行移植扩展,目前百试不爽呀!

路过

鸡蛋

鲜花

握手

雷人

发表评论 评论 (2 个评论)

回复 sw8sw8 2015-10-29 23:35
不要像我一样浪费青春了。以后的硬件足以支撑图形系统。现在的价格也就比它多个10多元
虽然现在可以跑些小系统做些简单的界面。到时候就都全部废弃。
回复 落叶行健ywm 2015-10-30 08:37
只是暂时这个很实用,所以就用了。其实也没折腾,关键是想搞清楚其中的思维吧