一、嵌入式的菜单模板之数据结构
1:菜单的组织形式第一步就是有个好的结构体。
//定义菜单类型
typedefenum
{
//0,1,2,...=parent&title,UISTR_SPACE-topmenu
UIMENU_POPUP=-1,/*有下级菜单*/
UIMENU_HASVALUE=-2,//此菜单有数值显示或设置
UIMENU_CUSTOM=-3,/*有需要用户确认界面*/
UIMENU_CUSTOM_HASVALUE=-4,
UIMENU_NOACTION=-5
}T_UI_MENUITEM_TYPE;
//主要的菜单数据结构
typedefstruct
{
u8nMenuStr;//菜单位置,主要是在另外一个枚举中索引
T_UI_MENUITEM_TYPEnType;//菜单类型,见上面定义的数据类型,可根据自己的实际情况自己扩展
}T_UI_MENUITEM;
2:自定义菜单主题名称
//菜单主题定义
enum
{
//第一组菜单
UISTR_MENU,//主菜单设置
UISTR_MENU_ONE,//平层设置
UISTR_MENU_TWO,//重量设置
UISTR_MENU_THR,//楼层学习
UISTR_MENU_FOU,//密码设置
//第二组菜单
//UISTR_MENU_ONE,
UISTR_MENU_ONE_ONE,//平层设置界面
UISTR_MENU_ONE_TWO,//上升补偿值显示
UISTR_MENU_ONE_THR,
UISTR_MENU_ONE_FOU,
//第三组菜单
//UISTR_MENU_TWO,
UISTR_MENU_TWO_ONE,//显示额定载重
UISTR_MENU_TWO_TWO,
UISTR_MENU_TWO_THR,
UISTR_MENU_TWO_FOU,
};
我上面只是一个模板,实际要根据情况设置自己能轻而易举识别的定义。
3:再次就是实际情况的菜单数组保存地方了。
constT_UI_MENUITEMg_uiMenuItemsSrc[MENU_ITEM_NUM]=
{
{UISTR_MENU,(T_UI_MENUITEM_TYPE)(u8)0},//带0结尾的都是主菜单,其下面是有子菜单选项的。
{UISTR_MENU_ONE,UIMENU_POPUP},//平层设置选项界面
{UISTR_MENU_TWO,UIMENU_CUSTOM},
{UISTR_MENU_THR,UIMENU_CUSTOM},
{UISTR_MENU_FOU,UIMENU_CUSTOM},
{UISTR_MENU_ONE,(T_UI_MENUITEM_TYPE)(u8)0},
{UISTR_MENU_ONE_ONE,UIMENU_CUSTOM},//平层设置界面
{UISTR_MENU_ONE_TWO,UIMENU_HASVALUE},//上升补偿值
{UISTR_MENU_ONE_THR,UIMENU_CUSTOM},
{UISTR_MENU_ONE_FOU,UIMENU_HASVALUE},
{UISTR_MENU_TWO,(T_UI_MENUITEM_TYPE)(u8)0},//1
{UISTR_MENU_TWO_ONE,UIMENU_HASVALUE},//额定载重
//{UISTR_MENU_TWO_TWO,UIMENU_CUSTOM},
//{UISTR_MENU_TWO_THR,UIMENU_CUSTOM},
//{UISTR_MENU_TWO_FOR,UIMENU_CUSTOM},
{-1,(T_UI_MENUITEM_TYPE)(u8)0},//菜单解析函数结束查找的标志
};
这个菜单数组保存了我们实际情况的菜单形式。他会被菜单解析函数解析出来,并按自定义规则显示出来。
二、菜单模板之菜单解析
第一步:绘制单一菜单
//绘制某个菜单,参数是菜单位置
voiduiProcMenu(u8nPopupMenuTitle)
{
u32nCount,nTopIndex=0,nCurrentIndex=0;
T_UI_MENUITEM*pUiStartMenuItem=&g_uiMenuItems[0],*pUiEndMenuItem;
u8nKey;
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)
{
caseUIKEY_OK:
if(pUiStartMenuItem[nCurrentIndex].nType==UIMENU_POPUP)//处理有下拉菜单的选项
{
uiProcMenu(pUiStartMenuItem[nCurrentIndex].nMenuStr);
}
elseif(pUiStartMenuItem[nCurrentIndex].nType==UIMENU_HASVALUE)//有值改变的情况处理
{
uiProcMenuHasValue(nPopupMenuTitle,&pUiStartMenuItem[nCurrentIndex],
1+(nCurrentIndex-nTopIndex),nCurrentIndex);
}
elseif(pUiStartMenuItem[nCurrentIndex].nType==UIMENU_CUSTOM)
{
///uiProcMenuCustom(nPopupMenuTitle,&pUiStartMenuItem[nCurrentIndex],1+(nCurrentIndex-nTopIndex));
}
uiProcMenuDraw(pUiStartMenuItem,nCount,nTopIndex,nCurrentIndex);
break;
caseUIKEY_UP:
if(nCurrentIndex>0)
nCurrentIndex--;
if(nCurrentIndex<nTopIndex)
nTopIndex=nCurrentIndex;
uiProcMenuDraw(pUiStartMenuItem,nCount,nTopIndex,nCurrentIndex);
break;
caseUIKEY_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:其他函数
//可用来过滤掉某些菜单不显示
voiduiProcMenuSettingStart(u32nPopupMenuTitle)
{
}
//这里主要用来最终判断每次退出一个菜单
//后是否有需要数据保存
voiduiProcMenuSettingEnd(u32nPopupMenuTitle)
{
//内容自己实现
}
3:实现绘制各个菜单函数,至于实现某个功能的函数,那就是细致下去的活了,自己把握
////绘画菜单界面
voiduiProcMenuDraw(T_UI_MENUITEM*pUiStartMenuItem,u32nCount,u32nTopIndex,u32nCurrentIndex)
{
u32i,nIndex;
u8bSelected;
//清除下界面
//uiLcdClear();
OLED_StartDraw();
OLED_ClrScr(0);
//显示菜单主题
switch((pUiStartMenuItem-1)->nMenuStr)//找type对应的值
{
caseUISTR_MENU:
Lcd_HZ_1212(UISTR_HZ_HBKJ,0,3,4);
break;
caseUISTR_MENU_ONE:
///uiLcd_1212_ch(UISTR_ZAIZHONG_SET_ZHONGLIANGZHILING,0,40,2);
Lcd_HZ_1212(UISTR_HZ_HJLC,0,3,4);
break;
caseUISTR_MENU_TWO:
//uiLcd_1212_ch(UISTR_PINGCHENG_SET,0,40,4);
Lcd_HZ_1212(UISTR_HZ_ZL,0,3,2);
break;
caseUISTR_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对应的值
{
//主菜单下的显示
caseUISTR_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;
caseUISTR_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;
caseUISTR_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;
caseUISTR_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;
//二级菜单下的显示
caseUISTR_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;
caseUISTR_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;
caseUISTR_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:实现有数值显示的,有下拉菜单的,有整个界面显示的功能。这些就是我们根据工程情况去自己实现的。
//画有值要显示的部分
voiduiProcMenuDrawValue(T_UI_MENUITEM*pUiMenuItem,introw,u8bIsReverse)
{
}
//处理有数值显示的
voiduiProcMenuHasValue(intnPopupMenuTitle,T_UI_MENUITEM*pUiMenuItem,introw,intnCurrentIndex)
{
}