// ========================================================================= // 函数功能:画状态条(最右边) // 输入参数:dispara:代表的显示参数 // 输出参数: // 返回值 : // 说明 :一般而言dispara的所有菜单项因为屏幕的原因不可能同时显示出来,此状态条 // 代表当前操作的菜单项在同层所有菜单中的位置 // ========================================================================= void drawstatecontent_9cell_rightside(struct menu_displaypara *dispara) { u8 numOp=0; u8 numTotal=0; s32 lengthT=0; s32 LengthE=0; struct tagRectangle state_area={0,0,0,0}; numOp=CalMenuitemNumber(dispara->OperatingMenuitem); numTotal=CalMenuitemNum(dispara->FVisualMenuitem); //复原颜色 state_area.left=dispara->CurWin->right-dispara->CurWin->left-cn_column_space; state_area.right=dispara->CurWin->right-dispara->CurWin->left; state_area.top=0; state_area.bottom=dispara->CurWin->bottom-dispara->CurWin->top; GK_ApiFillRect(dispara->CurWin, &state_area, color_back, 0,CN_FILLRECT_MODE_N,0); //标志当前的可视区 lengthT=state_area.bottom-state_area.top; //提高精度; lengthT=lengthT*1000; LengthE=(lengthT+numTotal-1)/numTotal; state_area.top=(numOp-1)*LengthE; state_area.top=(state_area.top)/1000; state_area.bottom=(numOp)*LengthE; state_area.bottom=(state_area.bottom)/1000; GK_ApiFillRect(dispara->CurWin, &state_area, color_light, 0,CN_FILLRECT_MODE_N,0); GK_ApiSyncShow(CN_TIMEOUT_FOREVER); return; }
// ========================================================================= // 函数功能:获取同层菜单项的第number个菜单项 // 输入参数:pMenuitem,同层菜单项,number,待寻找的菜单项的号码 // 输出参数: // 返回值 :同层菜单项的第number个菜单项 // 说明 :寻找的顺序是同层菜单项的嫡长子为第一个算起,采用循环取余的方法 // ========================================================================= struct menu_item *GetMenuitemBynumber(struct menu_item *pMenuitem, s8 number) { struct menu_item *result=NULL; u8 TotalNum=0; if(NULL==pMenuitem)//||(没有number为0的菜单项) { printf("Invalid parameter for GetMenuitemByNunber!\n"); return result; } TotalNum=CalMenuitemNum(pMenuitem); result=GetBBmenuitem(pMenuitem); //auto adjust the no of the searching menuitem,even the number is negative,we also adjust it while(number<=0)//这种情况需要调整 { number=number+TotalNum; } if(number>TotalNum) { number=number%TotalNum; } TotalNum=1; while(TotalNum!=number) { result=GetNextMenuitem(result); if(NULL==result) { break; } TotalNum++; } return result; }
/* static struct Rectangle CalDisAreaFromPre_9cell(struct menu_displaypara *pre,struct menu_displaypara *cur) { struct Rectangle result={0,0,0,0};//计算的结果 //内部调用,无需参数检查 cur->MenuitemSpace=cal_menuitemarea(cur->OperatingMenuitem); //根据罗总意见,不论是主菜单还是子菜单都是重新建立一个全页菜单。 return result; } */ struct Rectangle CalDisAreaFromPre_9cell(struct menu_displaypara *pre,struct menu_displaypara *cur) { u32 menuitem_num;//当前菜单有多少个菜单项 struct Rectangle result={0,0,0,0};//计算的结果 u8 number=0;//用于计算第几个窗口弹出的 s32 limit_end;//可视域边界点 s32 limit_start;//可视起点 s32 cal_end;//计算边界 s32 cal_start;//计算起点 s32 Midpoint;//中间位置 u32 length=0; //参数检测 if(NULL==cur) { printf("Invalid para for cal 9cell space!\n"); return result; } if(NULL==cur->FVisualMenuitem) { printf("Invalid para for cal 9cell space!\n"); return result; } cur->MenuitemSpace=cal_menuitemarea(cur->FVisualMenuitem); if(NULL==pre)//主菜单 { return result;//新建页 } else if(NULL==pre->pre)//主菜单弹出子菜单 { return result;//新建页 } else//这个要考虑多种情况,比较复杂 { menuitem_num=CalMenuitemNum(cur->FVisualMenuitem); number=CalDisBettween2Menuitem(pre->FVisualMenuitem, pre->OperatingMenuitem); //计算水平位置 limit_start=pre->MenuitemSpace.width+cn_space_margin; limit_end=cur->AppWin->absx0+cur->AppWin->right-cur->AppWin->left-pre->CurWin->absx0; cal_start=limit_start;//在九宫格中这两者是相同的 cal_end=cal_start+cur->MenuitemSpace.width+cn_space_margin; if(cal_end>limit_end)//水平位置不够,则一票否决 { return result; } else { result.left=cal_start; result.right=cal_end; } //计算垂直位置,记得放在中间 length=(cur->MenuitemSpace.height)*menuitem_num+cn_space_margin; limit_start=cur->AppWin->absy0-pre->CurWin->absy0; limit_end=limit_start+cur->AppWin->bottom-cur->AppWin->top; if(length>(limit_end-limit_start))//空间不富裕,不必考虑中间位置了 { result.top=limit_start; result.bottom=limit_end; return result; } else//有富余,考虑中间位置 { Midpoint=pre->MenuitemSpace.height*number+pre->MenuitemSpace.height/2; if(((Midpoint-limit_start)>=length/2)&&(limit_end-Midpoint)>=length/2)//两边都满足,可以放在中间 { result.top=Midpoint-length/2; result.bottom=length+result.top; } else if((Midpoint-limit_start)<length/2)//上边不够 { result.top=limit_start; result.bottom=length+result.top; } else//下边不够 { result.bottom=limit_end; result.top=result.bottom-length; } return result; } } }
// ========================================================================= // 函数功能:根据九格的形式进行显示项的调整 // 输入参数:待调整的显示参数dispara // 输出参数: // 返回值 : // 说明 :将修改显示参数的FVisualMenuitem和LVisualMenuitem,对于主菜单则不会修改, // 考虑了需要滚屏的情况,尽最大可能的显示更多的菜单项 // ========================================================================= void adjustvisualmenuitem_9cell(struct menu_displaypara *dispara) { u8 dis_num;//窗口可以显示的菜单项条目 u8 OperaNumber=0; u8 FVisualNumber=0; u8 LVisualNumber=0; s32 dis_height;//可视域的宽度 s32 deep_limit; s32 deep_cal; struct menu_item *BBmenuitem=NULL,*LBmenuitem=NULL,*tempmenuitem=NULL; //参数检查 if((NULL==dispara)||(NULL==dispara->OperatingMenuitem)) { printf("Invalid parameter----adjustvisualmenuitem_9cell\n"); return; } if(NULL==dispara->pre) { // printf("No need to adjsutVisualMenuitem for main menuitem!\n"); dis_num=9; } else { deep_cal=dispara->CurWin->absy0+dispara->CurWin->bottom-dispara->CurWin->top; deep_limit=dispara->AppWin->absy0+dispara->AppWin->bottom-dispara->AppWin->top; if(deep_cal>deep_limit)//有超出的部分 { dis_height=deep_limit-dispara->CurWin->absy0; } else { dis_height=deep_cal-dispara->CurWin->absy0; } if(dis_height==0) { printf("Menu space is NULL, so do nothing!\n"); return; } dis_num=dis_height/(dispara->MenuitemSpace.height); } BBmenuitem=GetBBmenuitem(dispara->OperatingMenuitem); LBmenuitem=GetLBmenuitem(dispara->OperatingMenuitem); tempmenuitem=dispara->OperatingMenuitem; if(dis_num>=CalMenuitemNum(dispara->OperatingMenuitem))//能够容纳全部; { dispara->FVisualMenuitem=BBmenuitem; dispara->LVisualMenuitem=LBmenuitem; } else//容纳不了 { //考虑翻页的情况 FVisualNumber=CalMenuitemNumber(dispara->FVisualMenuitem); LVisualNumber=CalMenuitemNumber(dispara->LVisualMenuitem); OperaNumber=CalMenuitemNumber(dispara->OperatingMenuitem); if(OperaNumber<FVisualNumber)//当前操作项已经转到第一显示项前面,向前翻一页 { if(dispara->OperatingMenuitem==BBmenuitem)//从最未位到达最前面,因为是循环的 { tempmenuitem=dispara->OperatingMenuitem; while(dis_num>1) //将LastVisual指针后调 { if(tempmenuitem==LBmenuitem) { break; } tempmenuitem=GetNextMenuitem(tempmenuitem); dis_num--; } dispara->LVisualMenuitem=tempmenuitem; dispara->FVisualMenuitem=dispara->OperatingMenuitem; } else//顺序到达的 { tempmenuitem=dispara->OperatingMenuitem; while(dis_num>1) //将SlayerFrist指针前调 { if(tempmenuitem==BBmenuitem) { break; } tempmenuitem=GetPreMenuitem(tempmenuitem); dis_num--; } dispara->FVisualMenuitem=tempmenuitem; dispara->LVisualMenuitem=dispara->OperatingMenuitem; } } else if(OperaNumber>LVisualNumber)//当前操作项已经转到最后显示项后面,向后翻一页 { if(dispara->OperatingMenuitem==LBmenuitem)//从最前位到达最后面,因为是循环的 { tempmenuitem=dispara->OperatingMenuitem; while(dis_num>1) //将FirstVisual指针后调 { if(tempmenuitem==BBmenuitem) { break; } tempmenuitem=GetPreMenuitem(tempmenuitem); dis_num--; } dispara->FVisualMenuitem=tempmenuitem; dispara->LVisualMenuitem=dispara->OperatingMenuitem; } else//顺序到达的 { tempmenuitem=dispara->OperatingMenuitem; while(dis_num>1) //将SlayerFrist指针前调 { if(tempmenuitem==LBmenuitem) { break; } tempmenuitem=GetNextMenuitem(tempmenuitem); dis_num--; } dispara->LVisualMenuitem=tempmenuitem; dispara->FVisualMenuitem=dispara->OperatingMenuitem; } } else//没有超出显示页,尽可能的显示多 { if(dis_num<=CalDisBettween2Menuitem(dispara->FVisualMenuitem, dispara->LVisualMenuitem))//在最初始分配的时候会出现 { tempmenuitem=dispara->OperatingMenuitem; while(dis_num>1) //将SlayerFrist指针前调 { if(tempmenuitem==BBmenuitem) { break; } tempmenuitem=GetPreMenuitem(tempmenuitem); dis_num--; } dispara->FVisualMenuitem=tempmenuitem; tempmenuitem=dispara->OperatingMenuitem; while(dis_num>1) //将SlayerLast指针后调 { if(tempmenuitem==LBmenuitem) { break; } tempmenuitem=GetNextMenuitem(tempmenuitem); dis_num--; } dispara->LVisualMenuitem=tempmenuitem; } else { //不予改变可视的第一项和最后一项 } } } //进行调试的信息,看看到底对否 // printf("BB_menuitem=%s\n",BBmenuitem->node.name); // printf("Fv_menuitem=%s\n",dispara->FVisualMenuitem->node.name); // printf("Op_menuitem=%s\n",dispara->OperatingMenuitem->node.name); // printf("Lv_menuitem=%s\n",dispara->LVisualMenuitem->node.name); // printf("LB_menuitem=%s\n\n",LBmenuitem->node.name); return; }
// ========================================================================= // 函数功能:为下拉模式分计算显示空间 // 输入参数:pre,前级显示参数,cur当前显示参数 // 输出参数: // 返回值 :通过计算得到的下拉模式主菜单或者子菜单所需的空间 // 说明 :pre为NULL,则证明是为主菜单分配空间,否则是为子菜单分配空间 // 该显示参数所占用的空间,当然,要依赖前级菜单 // 对于下拉显示模式而言,只有主菜单是横向,其余的都是纵向显示 // ========================================================================= //根据罗总的意见进行了修改 //对于主菜单,依然建立的是铺满整屏的窗口 //对于以及主菜单,建立在当前操作项的正下面(优先),如果位置不够,要向左移动。 //对于二级子菜单及其以后的子菜单,都优先建立在当前菜单的右边,如果右边位置不够,则建立在左边; struct tagRectangle CalDisAreaFromPre_pull(struct menu_displaypara *pre,struct menu_displaypara *cur) { u8 number=0;//用于计算第几个窗口弹出的 u32 menuitem_num;//当前菜单有多少个菜单项 s32 limit_end;//可视域边界点 s32 limit_start;//可视起点 s32 cal_end;//计算边界 s32 cal_start;//计算起点 s32 Midpoint;//中间位置 u32 length=0; s32 length_left=0;//存储可以划分的显示区域 s32 length_need=0;//存储需要的显示区域 struct tagRectangle result={0,0,0,0};//计算的结果 struct menu_displaypara *pMainMenuDispara;//暂时页节点 //只是内部调用,不再进行参数检测,以提高效率 cur->MenuitemSpace=cal_menuitemarea(cur->FVisualMenuitem); if(NULL==pre)//主菜单 { return result;//新建一个铺满整屏的窗口 } else//这个要考虑多种情况,比较复杂 { menuitem_num=CalMenuitemNum(cur->FVisualMenuitem); number=CalDisBettween2Menuitem(pre->FVisualMenuitem, pre->OperatingMenuitem); //计算水平位置 if(NULL==pre->pre)//前级是水平,即主菜单 { limit_start=(pre->MenuitemSpace.width)*number+cn_space_margin; limit_end=pre->CurWin->right-pre->CurWin->left; cal_start=limit_start; cal_end=cal_start+cur->MenuitemSpace.width+cn_space_margin; if(cal_end>limit_end)//水平位置不够,看看能否进行调整 { //右边不够,就向左移动,实在不够那就没有办法了 if((limit_end)>(cal_end-cal_start))//当前层还可以容纳下 { result.left=limit_end-cur->MenuitemSpace.width-cn_space_margin; result.right=limit_end; } else//容纳不下,一般的是不可能的,除非屏幕足够窄,或者当前菜单层太宽 { result.left=0; result.right=limit_end; } } else//水平位置够了 { result.left=cal_start; result.right=cal_end; } } else//二级子菜单及其以下,先看右边够不够,够用的话就右边,不够的话就左边, { length_need=cur->MenuitemSpace.width+cn_space_margin; length_left=pre->AppWin->absx0+pre->AppWin->right-pre->AppWin->left-pre->CurWin->right-pre->CurWin->absx0+pre->CurWin->left; if(length_need>length_left)//右边不够, { //看看左边够不够 length_left=pre->CurWin->absx0-pre->AppWin->absx0; length_need=cur->MenuitemSpace.width+cn_space_margin; if(length_need>length_left)//左边也不够 { //看看是左边多,还是右边多,哪边多就放哪边 length_need=pre->AppWin->absx0+pre->AppWin->right-pre->AppWin->left-pre->CurWin->right-pre->CurWin->absx0+pre->CurWin->left; if(length_left>length_need)//左边多 { result.left=-(length_left); result.right=0; } else//右边多 { result.left=pre->CurWin->right-pre->CurWin->left; result.right=result.left+length_need; } } else//左边够 { result.right=0; result.left=result.right-length_need; } } else//右边够 { result.left=pre->CurWin->right-pre->CurWin->left; result.right=result.left+length_need; } } //根据罗总的意见,都是在一页的。top和bottom受主菜单水平显示的限制 pMainMenuDispara=getmainmenudispara(pre);//获取主菜单 if(NULL==pMainMenuDispara) { printf("fata_err_in cal pull space!"); return result; } limit_start=pre->AppWin->absy0+pMainMenuDispara->MenuitemSpace.height+cn_space_margin-pre->CurWin->absy0; length_need=(cur->MenuitemSpace.height)*menuitem_num+cn_space_margin; limit_end=cur->AppWin->absy0+cur->AppWin->bottom-cur->AppWin->top-pre->CurWin->absy0; if(NULL==pre->pre)//直接在主菜单下,水平弹出垂直菜单 { if(length_need>(limit_end-limit_start))//考虑空间大小,空间不足,考虑分配整数个。 { result.top=limit_start; result.bottom=result.top+((limit_end-limit_start)/(cur->MenuitemSpace.height))*(cur->MenuitemSpace.height)+cn_space_margin; return result; } else { result.top=limit_start; result.bottom=result.top+length_need; return result; } } else//垂直弹出垂直菜单 { if(length_need>(limit_end-limit_start))//空间不富裕,不必考虑中间位置了 { result.top=limit_start; result.bottom=limit_end; return result; } else//有富余,考虑中间位置 { Midpoint=pre->MenuitemSpace.height*number+pre->MenuitemSpace.height/2; if(((Midpoint-limit_start)>=length_need/2)&&(limit_end-Midpoint)>=length_need/2)//两边都满足,可以放在中间 { result.top=Midpoint-length_need/2; result.bottom=length_need+result.top; } else if((Midpoint-limit_start)<length_need/2)//上边不够 { result.top=limit_start; result.bottom=length_need+result.top; } else//下边不够 { result.bottom=limit_end; result.top=result.bottom-length_need; } return result; } } } }
// ========================================================================= // 函数功能:根据下拉模进行显示项的调整 // 输入参数:待调整的显示参数dispara // 输出参数: // 返回值 : // 说明 :将修改显示参数的FVisualMenuitem和LVisualMenuitem,对于主菜单则不会修改, // 考虑了需要滚屏的情况,尽最大可能的显示更多的菜单项 // ========================================================================= void adjustvisualmenuitem_pull(struct menu_displaypara *dispara) { u8 dis_num;//窗口可以显示的菜单项条目 u8 OperaNumber=0; u8 FVisualNumber=0; u8 LVisualNumber=0; s32 length_Visual;//可视域的宽度 s32 length_E;//每条菜单项占用的长度,水平指的是width,垂直指的是height struct menu_item *BBmenuitem=NULL,*LBmenuitem=NULL,*tempmenuitem=NULL; //参数检查 if((NULL==dispara)||(NULL==dispara->OperatingMenuitem)) { printf("Invalid para for Adjust!\n"); return; } if(NULL==dispara->pre)//主菜单,横向 { length_Visual=dispara->CurWin->right-dispara->CurWin->left; // deep_limit=dispara->AppWin->absx0+dispara->AppWin->right-dispara->AppWin->left; length_E=dispara->MenuitemSpace.width; } else//子菜单,纵向 { length_Visual=dispara->CurWin->bottom-dispara->CurWin->top; // deep_limit=dispara->AppWin->absy0+dispara->AppWin->bottom-dispara->AppWin->top; length_E=dispara->MenuitemSpace.height; } if(length_E==0) { printf("Menu space is NULL, so do nothing!\n"); return; } dis_num=length_Visual/(length_E); BBmenuitem=GetBBmenuitem(dispara->OperatingMenuitem); LBmenuitem=GetLBmenuitem(dispara->OperatingMenuitem); tempmenuitem=dispara->OperatingMenuitem; if(dis_num>=CalMenuitemNum(dispara->OperatingMenuitem))//能够容纳全部; { dispara->FVisualMenuitem=BBmenuitem; dispara->LVisualMenuitem=LBmenuitem; } else//容纳不了 { //考虑翻页的情况 FVisualNumber=CalMenuitemNumber(dispara->FVisualMenuitem); LVisualNumber=CalMenuitemNumber(dispara->LVisualMenuitem); OperaNumber=CalMenuitemNumber(dispara->OperatingMenuitem); if(OperaNumber<FVisualNumber)//当前操作项已经转到第一显示项前面,向前翻一页 { if(dispara->OperatingMenuitem==BBmenuitem)//从最未位到达最前面,因为是循环的 { tempmenuitem=dispara->OperatingMenuitem; while(dis_num>1) //将LastVisual指针后调 { if(tempmenuitem==LBmenuitem) { break; } tempmenuitem=GetNextMenuitem(tempmenuitem); dis_num--; } dispara->LVisualMenuitem=tempmenuitem; dispara->FVisualMenuitem=dispara->OperatingMenuitem; } else//顺序到达的 { tempmenuitem=dispara->OperatingMenuitem; while(dis_num>1) //将SlayerFrist指针前调 { if(tempmenuitem==BBmenuitem) { break; } tempmenuitem=GetPreMenuitem(tempmenuitem); dis_num--; } dispara->FVisualMenuitem=tempmenuitem; dispara->LVisualMenuitem=dispara->OperatingMenuitem; } } else if(OperaNumber>LVisualNumber)//当前操作项已经转到最后显示项后面,向后翻一页 { if(dispara->OperatingMenuitem==LBmenuitem)//从最前位到达最后面,因为是循环的 { tempmenuitem=dispara->OperatingMenuitem; while(dis_num>1) //将FirstVisual指针后调 { if(tempmenuitem==BBmenuitem) { break; } tempmenuitem=GetPreMenuitem(tempmenuitem); dis_num--; } dispara->FVisualMenuitem=tempmenuitem; dispara->LVisualMenuitem=dispara->OperatingMenuitem; } else//顺序到达的 { tempmenuitem=dispara->OperatingMenuitem; while(dis_num>1) //将SlayerFrist指针前调 { if(tempmenuitem==LBmenuitem) { break; } tempmenuitem=GetNextMenuitem(tempmenuitem); dis_num--; } dispara->LVisualMenuitem=tempmenuitem; dispara->FVisualMenuitem=dispara->OperatingMenuitem; } } else//没有超出显示页,尽可能的显示多 { if(dis_num<=CalDisBettween2Menuitem(dispara->FVisualMenuitem, dispara->LVisualMenuitem))//在最初始分配的时候会出现 { tempmenuitem=dispara->OperatingMenuitem; while(dis_num>1) //将SlayerFrist指针前调 { if(tempmenuitem==BBmenuitem) { break; } tempmenuitem=GetPreMenuitem(tempmenuitem); dis_num--; } dispara->FVisualMenuitem=tempmenuitem; tempmenuitem=dispara->OperatingMenuitem; while(dis_num>1) //将SlayerLast指针后调 { if(tempmenuitem==LBmenuitem) { break; } tempmenuitem=GetNextMenuitem(tempmenuitem); dis_num--; } dispara->LVisualMenuitem=tempmenuitem; } else { //不予改变可视的第一项和最后一项 } } } //进行调试的信息,进行显示校对,看是否正确。 // printf("BB_menuitem=%s\n",BBmenuitem->node.name); // printf("Fv_menuitem=%s\n",dispara->FVisualMenuitem->node.name); // printf("Op_menuitem=%s\n",dispara->OperatingMenuitem->node.name); // printf("Lv_menuitem=%s\n",dispara->LVisualMenuitem->node.name); // printf("LB_menuitem=%s\n\n",LBmenuitem->node.name); return; }