📄 q_menu.cpp
字号:
#include "qcurses/Q_Menu.hpp"/*#################################################################################################################修改意向 2004年12月14日 准备增强菜单的左右移动功能,比如移动最右边自动打到最左边*///#################################################################################################################//菜单函数---菜单项Q_MenuItem::Q_MenuItem(int flag,char *name,bool sub,int upflag){ M_Flag = flag; strcpy(M_Name,name); M_Sub = sub; M_UpFlag = upflag; M_LEN=strlen(M_Name);}//#################################################################################################################//菜单函数---子菜单项Q_SubMenuItem::Q_SubMenuItem(){ Count=0; SubWidth=0;}//-----------------------------------------------------------------------------------void Q_SubMenuItem::ComputSubWidth(){ int i=0; SubWidth=0; for (i=0;i<Count;i++) { if (SM_Item[i]->M_LEN>SubWidth) SubWidth=SM_Item[i]->M_LEN; }}//-----------------------------------------------------------------------------------bool Q_SubMenuItem::AddSubMenuItem(Q_MenuItem *Items){ //控制在 20 个以内 if (Count>=20) return(false); SM_Item[Count] = Items; //计算最大宽度 if (Items->M_LEN>SubWidth) SubWidth=Items->M_LEN; Count++; return(true);}//#################################################################################################################//菜单函数---子菜单项Q_MenuList::Q_MenuList(WINDOW *vMainWin,int vHeight,int vWidth,int vYBegin,int vXBegin,bool vBox,int vCFront,int vCBack,int vMaxCount):Q_List(vMainWin, vHeight, vWidth, vYBegin, vXBegin, vBox, vCFront, vCBack, vMaxCount){}//-----------------------------------------------------------------------------------bool Q_MenuList::isCheckBreak(int& Key){ if (Key==10) return(true); if (Key==KEY_LEFT) return(true);// if (Key==KEY_RIGHT)// return(false); return(false);}//#################################################################################################################//菜单函数---菜单实现函数Q_Menu::Q_Menu(WINDOW *vMainWin,int vWidth,int vYBegin,int vXBegin,bool vBox,int vCFront,int vCBack):Q_Object(vMainWin, 3, vWidth, vYBegin, vXBegin, vBox, vCFront, vCBack){ Count = 0; MenuJG = 1; SubFloor = 0; MainItemCount=0;}//-----------------------------------------------------------------------------------void Q_Menu::DispMenu(){ int NowCol=0; touchwin(WorkWin); wrefresh(WorkWin); MainItemCount=0; if (Count<=0) return; for (int i=0;i<Count;i++) { if (MenuItems[i]->M_UpFlag!=0) continue; if (i==0) { mvwaddstr(WorkWin,1,2,MenuItems[i]->M_Name); MainMenuItem[MainItemCount]=MenuItems[i]; NowCol+=(2+MenuJG+MenuItems[i]->M_LEN); MainItemCount++; continue; } mvwaddstr(WorkWin,1,NowCol,MenuItems[i]->M_Name); MainMenuItem[MainItemCount]=MenuItems[i]; NowCol+=(MenuJG+MenuItems[i-1]->M_LEN); MainItemCount++; } wattron(WorkWin,A_REVERSE); mvwaddstr(WorkWin,1,2,MainMenuItem[0]->M_Name); wattroff(WorkWin,A_REVERSE); wrefresh(WorkWin);}//-----------------------------------------------------------------------------------int Q_Menu::Get(){ Q_MenuItem *SelectEdMainMenuItem; Q_SubMenuItem *SubLevel0; Q_SubMenuItem *SubLevel1; Q_SubMenuItem *SubLevel2; //最多3层 int x1,y1,x2,y2,x3,y3; for (;;) { //首先取得主菜单的选项 for (;;) { SelectEdMainMenuItem = GetMainMenuItem(); if(NowKey==10) break; if(isCheckBreak(NowKey)) //类退出键 return(NowKey); } if (SelectEdMainMenuItem==NULL) return(-1); NowKey=0; getsyx(x1,y1); //只所以要+6是要加入边框和上下剪头的位置 SubLevel0 = MakeSubItem(SelectEdMainMenuItem); if (SubLevel0->Count<=0 || SubLevel0==NULL) continue; //是否超过屏幕最大宽度(等于当前子宽度+上一级别菜单宽度) if (y1+6+SubLevel0->SubWidth>80) y1=80-SubLevel0->SubWidth-4; //是否超过屏幕最大高度 if (x1-2+SubLevel0->Count+2>24) { SubWin[0] = newwin(24-(x1+SubLevel0->Count+2)+24-1,SubLevel0->SubWidth+6,x1+2,y1-SelectEdMainMenuItem->M_LEN); SubMenuList[0] = new Q_MenuList(SubWin[0],24-(x1+SubLevel0->Count+2)+24-1,SubLevel0->SubWidth+6,0,0,true,CFront,CBack); } else { SubWin[0] = newwin(SubLevel0->Count+2,SubLevel0->SubWidth+6,x1+2,y1-SelectEdMainMenuItem->M_LEN); SubMenuList[0] = new Q_MenuList(SubWin[0],SubLevel0->Count+2,SubLevel0->SubWidth+6,0,0,true,CFront,CBack); } SubMenuList[0]->Clear(); for (int i=0;i<SubLevel0->Count;i++) SubMenuList[0]->Add(SubLevel0->SM_Item[i]->M_Name);Level1: SubMenuList[0]->Get(); if(SubMenuList[0]->GetNowKey()==KEY_LEFT) //如果输入了 BACK 就返回上层 { delete SubMenuList[0]; delwin(SubWin[0]); touchwin(MainWin); wrefresh(MainWin); continue; } //第二级菜单 getsyx(x2,y2); SubLevel1 = MakeSubItem(SubLevel0->SM_Item[SubMenuList[0]->GetIndex()]); if (SubLevel1->Count<=0 && (SubMenuList[0]->GetNowKey()==10 || SubMenuList[0]->GetNowKey()==KEY_RIGHT)) { SelectEdMenuItem = SubLevel0->SM_Item[SubMenuList[0]->GetIndex()]; delete SubMenuList[0]; delwin(SubWin[0]); break; } //是否超过屏幕最大宽度(等于当前子宽度+上一级别菜单宽度) if (y2+6+SubLevel1->SubWidth+6>80) y2=y2-6-SubLevel1->SubWidth-SubLevel0->SM_Item[SubMenuList[0]->GetIndex()]->M_LEN-6; if (x2+SubLevel1->Count+2>24) { SubWin[1] = newwin(24-(x2+SubLevel1->Count+2)+24-1,SubLevel1->SubWidth+6,x2-1,y2+4); SubMenuList[1] = new Q_MenuList(SubWin[1],24-(x2+SubLevel1->Count+2)+24-1,SubLevel1->SubWidth+6,0,0,true,CFront,CBack); } else { SubWin[1] = newwin(SubLevel1->Count+2,SubLevel1->SubWidth+6,x2-1,y2+4); SubMenuList[1] = new Q_MenuList(SubWin[1],SubLevel1->Count+2,SubLevel1->SubWidth+6,0,0,true,CFront,CBack); } SubMenuList[1]->Clear(); for (int i=0;i<SubLevel1->Count;i++) { SubMenuList[1]->Add(SubLevel1->SM_Item[i]->M_Name); }Level2: SubMenuList[1]->Get(); if(SubMenuList[1]->GetNowKey()==KEY_LEFT) //如果输入了 BACK 就返回到上层 { delete SubMenuList[1]; delwin(SubWin[1]); touchwin(MainWin); wrefresh(MainWin); touchwin(SubWin[0]); wrefresh(SubWin[0]); goto Level1; } //第三级菜单 getsyx(x3,y3); SubLevel2 = MakeSubItem(SubLevel1->SM_Item[SubMenuList[1]->GetIndex()]); if (SubLevel2->Count<=0 && (SubMenuList[1]->GetNowKey()==10 || SubMenuList[1]->GetNowKey()==KEY_RIGHT)) { SelectEdMenuItem = SubLevel1->SM_Item[SubMenuList[1]->GetIndex()]; delete SubMenuList[0]; delwin(SubWin[0]); delete SubMenuList[1]; delwin(SubWin[1]); break; } //是否超过屏幕最大宽度(等于当前子宽度+上一级别菜单宽度) if (y3+4+SubLevel2->SubWidth+6>80) y3=80-8-SubLevel2->SubWidth-6-SubLevel1->SM_Item[SubMenuList[1]->GetIndex()]->M_LEN-6; //是否超过屏幕最大高度 if (x3-1+SubLevel2->Count+2>24) { SubWin[2] = newwin(24-(x3+SubLevel2->Count+2)+24-1,SubLevel2->SubWidth+6,x3-1,y3+4); SubMenuList[2] = new Q_MenuList(SubWin[2],24-(x3+SubLevel2->Count+2)+24-1,SubLevel2->SubWidth+6,0,0,true,CFront,CBack); } else { SubWin[2] = newwin(SubLevel2->Count+2,SubLevel2->SubWidth+6,x3-1,y3+4); SubMenuList[2] = new Q_MenuList(SubWin[2],SubLevel2->Count+2,SubLevel2->SubWidth+6,0,0,true,CFront,CBack); } SubMenuList[2]->Clear(); for (int i=0;i<SubLevel2->Count;i++) SubMenuList[2]->Add(SubLevel2->SM_Item[i]->M_Name); SubMenuList[2]->Get(); if(SubMenuList[2]->GetNowKey()==KEY_LEFT) //如果输入了 BACK 就返回到上层 { delete SubMenuList[2]; delwin(SubWin[2]); touchwin(MainWin); wrefresh(MainWin); touchwin(SubWin[0]); wrefresh(SubWin[0]); goto Level2; } if (SubMenuList[2]->GetNowKey()==10 || SubMenuList[2]->GetNowKey()==KEY_RIGHT) { SelectEdMenuItem = SubLevel2->SM_Item[SubMenuList[2]->GetIndex()]; delete SubMenuList[0]; delwin(SubWin[0]); delete SubMenuList[1]; delwin(SubWin[1]); delete SubMenuList[2]; delwin(SubWin[2]); break; } } touchwin(MainWin); wrefresh(MainWin); return(NowKey);}//-----------------------------------------------------------------------------------Q_MenuItem *Q_Menu::GetMainMenuItem(){ int NowCol=2,i=0; if (MainItemCount<=0) return(NULL); DispMenu(); for (;;) { GetKey(); if(isCheckBreak(NowKey)) //类退出键 break; wattroff(WorkWin,A_REVERSE); mvwaddstr(WorkWin,1,NowCol,MainMenuItem[i]->M_Name); if(NowKey==KEY_LEFT) { if (i<=0) { NowCol=2; i=MainItemCount-1; for (int j=0;j<MainItemCount-1;j++) { if (j==0) NowCol+=(MenuJG+MainMenuItem[j]->M_LEN); else NowCol+=(MenuJG+MainMenuItem[j-1]->M_LEN); } } else { NowCol=2; for (int j=0;j<i-1;j++) { if (j==0) NowCol+=(MenuJG+MainMenuItem[j]->M_LEN); else NowCol+=(MenuJG+MainMenuItem[j-1]->M_LEN); } i--; } } if(NowKey==KEY_RIGHT) { if (i>=MainItemCount-1) { i=0; NowCol=2; } else { if (i==0) NowCol+=(MenuJG+MainMenuItem[i]->M_LEN); else NowCol+=(MenuJG+MainMenuItem[i-1]->M_LEN); i++; } } wattron(WorkWin,A_REVERSE); mvwaddstr(WorkWin,1,NowCol,MainMenuItem[i]->M_Name); wattroff(WorkWin,A_REVERSE); wrefresh(WorkWin); } wattron(WorkWin,A_REVERSE); mvwaddstr(WorkWin,1,NowCol,MainMenuItem[i]->M_Name); wattroff(WorkWin,A_REVERSE); wrefresh(WorkWin); return(MainMenuItem[i]);}//-----------------------------------------------------------------------------------void Q_Menu::AddMenu(int flag,char *name,bool sub,int upflag){ MenuItems[Count] = new Q_MenuItem(flag,name,sub,upflag); DispMenu(); Count++;}//-----------------------------------------------------------------------------------void Q_Menu::SetSpace(int JG){ MenuJG=JG;}//-----------------------------------------------------------------------------------Q_SubMenuItem *Q_Menu::MakeSubItem(Q_MenuItem *MMenu){ Q_SubMenuItem *SUBM = new Q_SubMenuItem; int i=0,j=0; for (i=0;i<Count;i++) { if (MenuItems[i]->M_UpFlag==MMenu->M_Flag) { if(!SUBM->AddSubMenuItem(MenuItems[i])) return(NULL); else j++; } } if (j<=0) { SUBM->Count = 0; return(SUBM); } return(SUBM);}//-----------------------------------------------------------------------------------bool Q_Menu::isCheckBreak(int &Key){ if (Key==8) return(true); if (Key==10) return(true); return(false);}//-----------------------------------------------------------------------------------Q_MenuItem *Q_Menu::GetSelectedMenu(){ return(SelectEdMenuItem);}//-----------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -