<br />/*******************************************************************************<br />*<br />菜单控制<br />模块退出时必须向菜单管理发出菜单关闭消息<br />********************************************************************************/<br /><br />#include <iom128v.h><br />#include <macros.h><br />#include <Eeprom.h><br /><br />#include "Const.h"<br />#include "EepromEnum.h"<br />#include "News.h"<br />#include "NewsEnum.h"<br />#include "Window.h"<br />#include "Source.h"<br /><br />#include "LcdDrive.h"<br />#include "Timer.h"<br />#include "CpuEeprom.h"<br />#include "Serial.h"<br />#include "Math.h"<br />#include "Sound.h"<br /><br />enum{<br /> eLEFT,<br /> eRIGHT<br />};<br /><br />#define TIME_MENULIMIT 40 //菜单显示时间<br /><br />static unsigned char mMenu_TimeLimit; //控制菜单显示时间,以秒为单位<br /><br />static unsigned char mMenu_Id; //在使用的菜单的层里面的索引<br />static unsigned char mMenu_ItemId; //菜单层的项索引<br />static unsigned char fMenu_Select; /*=1菜单选中了,已经离开菜<br />单,执行功能去了,执行完返回控制给菜单,会清0*/<br /><br />static unsigned char fMenu_RequStore; /*菜单选择有效请求,模块响应<br />后,退出时发nMenu_ReturnControl,控制权交回菜单*/<br /><br />/******************************************************************<br />菜单结构定义<br />******************************************************************/<br />struct MenuUnit{ //菜单单元结构<br /> unsigned char mX;<br /> unsigned char mY;<br /><br /> unsigned char Str[6]; //显示的字符串<br /><br /> unsigned char mSubId; /*选中后执行的子菜单一层的ID,==0无,和mNewsId关联*/<br /> unsigned char mNewsId; /*选中后执行的消息ID,==0无,和mSubId关联*/<br /><br /> unsigned char mReturnId; /*退出后执行的菜单层的ID号,==0相当关闭,由本身*/<br />};<br /><br />static const struct MenuUnit *psMenuCurrentUnit;<br /><br />/******************************************************************<br />菜单构造<br /> x,y, 字符串 要执行的ID,要执行的消息 返回执行的ID<br />******************************************************************/<br />const struct MenuUnit sMenuUnit_Close[]={ //每行是个SubId.关闭菜单,ID=0<br /> 0,9, "x097", 0, nXxx0_On, 0, //关闭菜单<br />};<br /><br />const struct MenuUnit sMenuUnit_Main[]={ //每行是个SubId.主菜单,ID=1<br /> 0,9, "x090", 2, 0, 0, //<br /> 20,9, "x091", 0, nXxx1_On, 0, //<br /> 40,9, "x092", 0, nXxx2_SetupOn, 0, //设置<br /> 60,9, "x098", 3, nSetVolume_On, 0, //参数调节,执行ID=3的菜单<br /> 80,9, "x099", 0, nPrinter_SetupOn, 0, //打印设置<br /> 100,9, "x096", 0, 0, 0, //BACK,向上回去<br />};<br /><br />const struct MenuUnit sMenuUnit_Moudel[]={ //每行是个SubId.模块菜单,ID=2<br /> 0,4, "Xxx31", 0, nXxx30_SetupOn, 0, //Xxx30<br /> 36,4, "Xxx32", 0, nXxx31_SetupOn, 0, //Xxx31<br /> 72,4, "Xxx4", 0, nXxx4_SetupOn, 0, //Xxx4<br /> 0,14, "Xxx5", 0, nXxx5_SetupOn, 0, //Xxx5<br /> 36,14, "Xxx5", 0, nXxx5_SetupOn, 0, //Xxx5<br /> 72,14, "Xxx5", 0, nXxx5_SetupOn, 0, //Xxx5<br /> 108,9, "x096", 1, 0, 0, //BACK,向上回去<br />};<br /><br />const struct MenuUnit sMenuUnit_AdjVolume[]={ //每行是个SubId.参数调节菜单,ID=3<br /> 0,9, "x094", 0, nSetAlarmVolume_On, 4, //声音,返回执行ID=4,继续报警音量调节<br />};<br /><br />const struct MenuUnit sMenuUnit_AdjAlarm[]={ //每行是个SubId.参数调节菜单,ID=4<br /> 0,9, "x094", 0, nSetLight_On, 5, //声音,返回执行ID=5,继续亮度<br />};<br /><br />const struct MenuUnit sMenuUnit_AdjLight[]={ //每行是个SubId.参数调节菜单,ID=5<br /> 0,9, "x094", 0, 0, 0, //亮度,返回执行ID=0.<br />};<br /><br />//一层菜单,有很多菜单单元组成<br />const struct MenuUnit * const psMenuLayer[]={<br /> sMenuUnit_Close, //ID=0,关闭菜单<br /> sMenuUnit_Main, //ID=1,主菜单<br /> sMenuUnit_Moudel, //ID=2,模块选择<br /> sMenuUnit_AdjVolume, //ID=3,设置音量<br /> sMenuUnit_AdjAlarm, //ID=4,设置报警音量<br /> sMenuUnit_AdjLight, //ID=5,亮度调节<br />};<br /><br />const unsigned char mMenuLayerMax[]={<br /> sizeof(sMenuUnit_Close)/sizeof(struct MenuUnit), //ID=0,关闭菜单<br /> sizeof(sMenuUnit_Main)/sizeof(struct MenuUnit), //ID=1,主菜单<br /> sizeof(sMenuUnit_Moudel)/sizeof(struct MenuUnit), //ID=2,模块选择<br /> sizeof(sMenuUnit_AdjVolume)/sizeof(struct MenuUnit), //ID=3,设置音量<br /> sizeof(sMenuUnit_AdjAlarm)/sizeof(struct MenuUnit), //ID=4,设置报警音量<br /> sizeof(sMenuUnit_AdjLight)/sizeof(struct MenuUnit), //ID=5,亮度调节<br />};<br /><br />#define dSPEEDKEY_MenuId 1 //快捷键对应功能的菜单项<br />#define dSPEEDKEY_MenuItemId 0 //快捷键对应功能的菜单项中的选项<br /><br />/******************************************************************<br />清除菜单区域<br />******************************************************************/<br />void InMenuWindowCls(void)<br />{<br /> Lcd_SetupId(Eeprom_Read(eP_DW_Menu));<br /> LcdData_ClrScreen( (em_BLACK<<4)+em_BLACK );<br />}<br /><br />/******************************************************************<br />显示当前菜单<br />必须窗口有效<br />只有一项时不反白显示.这样关闭菜单或单参数菜单不反白。<br />已经设置好全局的菜单指针<br />******************************************************************/<br />void InMeun_DispItem(unsigned char mId)<br />{<br /> Lcd_SetupId(Eeprom_Read(eP_DW_Menu));<br /> if(LcdData_WindowVisible()==False)return;<br /><br /> psMenuCurrentUnit=&(psMenuLayer[mMenu_Id])[mId]; //得到当前菜单项的结构指针<br /><br /> LcdData_MoveTo( (*psMenuCurrentUnit).mX,(*psMenuCurrentUnit).mY );<br /> if((mId==mMenu_ItemId)&&(mMenuLayerMax[mMenu_Id]>1)){<br /> //反白显示<br /> LcdData_SwapColor();<br /> }<br /> LcdData_CodeStrings( (*psMenuCurrentUnit).Str,em_CharOverlay );<br /><br /> psMenuCurrentUnit=&(psMenuLayer[mMenu_Id])[mMenu_ItemId]; //得到当前菜单项的结构指针<br />}<br /><br />/******************************************************************<br />移动<br />mXxx1=eLEFT,左,否则右<br />******************************************************************/<br />void InMeun_MoveItem(unsigned char mXxx1)<br />{<br />unsigned char i;<br /><br /> if(mMenu_Id==0){<br /> //展开<br /> mMenu_Id=1;<br /> mMenu_ItemId=0;<br /><br /> for(i=0;i<mMenuLayerMax[1];i++){<br /> InMeun_DispItem(i);<br /> }<br /> }<br /> else {<br /> if(mXxx1==eLEFT){<br /> i=mMenu_ItemId;<br /> if(mMenu_ItemId==0){<br /> mMenu_ItemId=mMenuLayerMax[mMenu_Id]-1;<br /> }<br /> else mMenu_ItemId--;<br /> }<br /> else {<br /> i=mMenu_ItemId++;<br /> if(mMenu_ItemId==mMenuLayerMax[mMenu_Id]){<br /> mMenu_ItemId=0;<br /> }<br /> }<br /> InMeun_DispItem(i);<br /> InMeun_DispItem(mMenu_ItemId);<br /> }<br />}<br /><br />/******************************************************************<br />显示全部菜单项,并设置相应参数<br />******************************************************************/<br />void InMenu_DispNewMenuItem(unsigned char mItem)<br />{<br />unsigned char i,j;<br /><br /> InMenuWindowCls();<br /> mMenu_ItemId=0;<br /> mMenu_Id=mItem;<br /><br /> j=mMenuLayerMax[mMenu_Id];<br /><br /> for(i=0;i<j;i++)InMeun_DispItem(i);<br />}<br /><br /><br />/******************************************************************<br />菜单确认时执行动作<br />******************************************************************/<br />void InMenu_Valid(void)<br />{<br /> if((fMenu_RequStore)||(fMenu_Select))return;<br /><br /> if( (*psMenuCurrentUnit).mNewsId>0){<br /> //有消息,改变当前消息。<br /> fMenu_RequStore=(*psMenuCurrentUnit).mNewsId; //有选择,等待模块返回<br /> fMenu_Select=1; //选择有效<br /><br /> News_Push(fMenu_RequStore);<br /> if((*psMenuCurrentUnit).mSubId>0){<br /> //有子菜单命令,执行<br /> InMenu_DispNewMenuItem((*psMenuCurrentUnit).mSubId);<br /> }<br /> }<br /> else {<br /> InMenu_DispNewMenuItem((*psMenuCurrentUnit).mSubId);<br /> }<br />}<br /><br />/******************************************************************<br />主菜单选中时,执行的转换或相应处理<br />转发消息<br />******************************************************************/<br />void InMenu_ChangeNews(void)<br />{<br /> News_Replace((*psMenuCurrentUnit).mNewsId+1+gNews_Word-eNews_KeySpeed);<br />}<br /><br />/******************************************************************<br />菜单中的消息转换的消息处理:eNews_beign<br />******************************************************************/<br />void Menu_NewsPreProcess(void)<br />{<br /> if(gNews_Word<eNews_KeySpeed){<br /> switch(gNews_Word){<br /> case eNews_KeyPush0: //<br /> Timer3_Switch();<br /> break;<br /><br /> case eNews_KeyPush1: //Xxx5<br /> News_Replace(nXxx5_Ctl_Key);<br /> break;<br /><br /> case eNews_KeyPush2: //<br /> News_Replace(nSound_ClockSwitch);<br /> break;<br /><br /> case eNews_KeyPush3: //保留<br /> News_Pop();<br /> break;<br /> }<br /> return;<br /> }<br /><br /> if( gNews_Word>eNews_KeyPushReturn )return; //只对快捷键,左,右,回车控制<br /><br /> mMenu_TimeLimit=0; //清计时器<br /><br /><br /> if(fMenu_Select==1){<br /> InMenu_ChangeNews(); //已经在有效状态,转换消息<br /> return;<br /> }<br /><br /> //在菜单控制下<br /> switch(gNews_Word){<br /> case eNews_KeySpeed: //快捷键<br /> News_Pop();<br /> if(mMenu_Id){<br /> //菜单已经展开,关闭菜单<br /> InMenu_DispNewMenuItem(0);<br /> }<br /> else {<br /> //直接进入快捷键对应的菜单选项<br /> mMenu_ItemId=dSPEEDKEY_MenuItemId;<br /> mMenu_Id=dSPEEDKEY_MenuId;<br /><br /> InMenu_Valid(); //菜单有效<br /> }<br /> break;<br /><br /> case eNews_KeyPushLeft:<br /> News_Pop();<br /> InMeun_MoveItem(eLEFT);<br /> break;<br /><br /> case eNews_KeyPushRight:<br /> News_Pop();<br /> InMeun_MoveItem(eRIGHT);<br /> break;<br /><br /> case eNews_KeyPushReturn: //对当前选中<br /> News_Pop();<br /> InMenu_Valid(); //菜单有效<br /> break;<br /> }<br />}<br /><br />/******************************************************************<br />菜单中的消息滞后处理,处理未被接收和处理的消息。<br />属于菜单发出的模块消息,未被接收,将是菜单退出,并清除该消息<br />******************************************************************/<br />void Menu_NewsLagProcess(void)<br />{<br />unsigned char i;<br /> if(gNews_Word==fMenu_RequStore){<br /> //向模块发出的消息未被接受,且菜单在Select状态,退出到上层<br /> fMenu_RequStore=fMenu_Select=0;<br /> InMenu_DispNewMenuItem((*psMenuCurrentUnit).mReturnId); //返回时显示的菜单项<br /> }<br /> //销毁<br /> i=News_Pop();<br /> while(i){i--;News_Pop();}<br />}<br /><br />/******************************************************************<br />菜单中的消息处理:<br />模块退出返回的消息<br />执行当前菜单的返回ID<br />******************************************************************/<br />void Menu_NewsProcess(void)<br />{<br />unsigned char i;<br /><br /> i=gNews_Word;<br /> News_Pop(); //接受消息<br /><br /> switch(i){<br /> case nMenu_ReturnControl:<br /> fMenu_RequStore=fMenu_Select=0; //选择无效状态<br /> InMenu_DispNewMenuItem((*psMenuCurrentUnit).mReturnId); //返回时显示的菜单项<br /> break;<br /><br /> case nMenu_OverFlow: //菜单时间到<br /> if(fMenu_Select){<br /> News_PreInsert(eNews_KeySpeed); //快捷<br /> }<br /> else {<br /> fMenu_RequStore=fMenu_Select=0;<br /> InMenu_DispNewMenuItem(0); //菜单回根<br /> }<br /> break;<br /> }<br />}<br /><br />/******************************************************************<br />菜单循环控制,主要显示延时控制<br />1S进入<br />******************************************************************/<br />void Menu_Loop(void)<br />{<br /> if( (fMenu_Select)||(mMenu_Id) ){<br /><br /> if(++mMenu_TimeLimit>=TIME_MENULIMIT){<br /> //超时,关闭菜单动作<br /> mMenu_TimeLimit=0;<br /> News_Push(nMenu_OverFlow); //菜单时间到<br /> }<br /> }<br />}<br /><br />/******************************************************************<br />菜单初始化<br />******************************************************************/<br />void Menu_Init(void)<br />{<br /> mMenu_TimeLimit=0;<br /> fMenu_RequStore=fMenu_Select=0; //选择无效状态<br /> InMenu_DispNewMenuItem(0); //菜单回根<br /><br /> //预处理消息注册<br /> News_Register(Menu_NewsPreProcess,eNews_beign,eNews_beign);<br /><br /> //滞后处理消息注册<br /> News_Register(Menu_NewsLagProcess,eNews_Lag,eNews_Lag);<br /><br /> //本模块使用的消息处理函数<br /> News_Register(Menu_NewsProcess,nMenu_ReturnControl,nMenu_OverFlow);<br />}
|