⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 menubar.c

📁 ARM_CORTEX-M3应用实例开发详解光盘
💻 C
字号:
#include "Menu.h"

extern GUI_RECT grTitle ;

void TitleBar(char * ptitle)
{
    unsigned int tm;

    GUI_SetFont(MENU_TF);
    tm = GUI_SetTextMode(GUI_TM_TRANS);
    GUI_DispStringInRect((char *)ptitle, &grTitle, GUI_TA_HCENTER|GUI_TA_VCENTER);     
    tm = GUI_SetTextMode(tm);
    GUI_SetFont(MENU_CF);
}

/*
 * 右边滚动条显示
 */

GUI_RECT grScroll = {SCROLLBARX, SCROLLBARY, 
                    SCROLLBARX + SCROLLBARW -1, SCROLLBARY + SCROLLBARH};
void ScrollBar(char i, char its, char wh, char percent)
{
#if 0
        GUI_ClearRect(grScroll.x0+1, grScroll.y0+1, grScroll.x1-1, grScroll.y1-1);
 
        GUI_DrawHLine(grScroll.y0, grScroll.x0, grScroll.x1);
        GUI_DrawHLine(grScroll.y1, grScroll.x0, grScroll.x1);
        GUI_DrawLine(grScroll.x0, grScroll.y0, grScroll.x0, grScroll.y1);
        GUI_DrawLine(grScroll.x1, grScroll.y0, grScroll.x1, grScroll.y1);

{
    int x0 = grScroll.x0+2, y0 = grScroll.y0+2, x1 = grScroll.x1-2, y1 = grScroll.y1-2;
    int sh;
 
    //计算滚动条的长度
    if (its > DispMax) {
        sh = (SCROLLBARH-4)/its;
        y1 -= sh * (its - DispMax);
    }
    //计算滚动条的位置
    if (i>wh) {
        y0 += sh * ((i-wh));
        y1 += sh * ((i-wh));
    }
    GUI_DrawHLine(y0, x0, x1);
    GUI_DrawHLine(y1, x0, x1);
    GUI_DrawLine(x0, y0, x0, y1);
    GUI_DrawLine(x1, y0, x1, y1);
}
#endif
}

/*
*****************************************************************************
* BarDisp - Bar型菜单显示
* DESCRIPTION: -
*
* @Para s:BAR显示的文字内容
* @Para X:X轴坐标
* @Para Y:Y轴坐标
* @Para HighLight:1--->高亮显示当前项  0--->普通显示当前项
//HightLight = 1--->HightLight Disp
//HightLight = 0--->Normal Disp
* Return :
*
*****************************************************************************
*/
void BarText(char *s, int X, int Y)
{
    GUI_RECT rt;
    unsigned int tm;

    rt.x0 = X, rt.y0 = Y;
    rt.x1 = X + BarXSize;
    rt.y1 = Y + BarYSize;

    tm = GUI_SetTextMode(GUI_TM_TRANS);
    GUI_DispStringInRect((char *)s, &rt, GUI_TA_VCENTER);
    GUI_SetTextMode(tm);
}
void BarDisp(char *s,int X,int Y,char HighLight)
{
//    GUI_RECT rt;
 
//    rt.x0 = X, rt.y0 = Y;
//    rt.x1 = X + BarXSize;
//    rt.y1 = Y + BarYSize;


    if (HighLight == 1) { //高亮显示

        MenuHigLight(X, Y, BarXSize, BarYSize, 1);

    } else {  //通常显示
        //显示Bar的Text
        MenuHigLight(X, Y, BarXSize, BarYSize, 0);
    }
}

/*
FIXME!!!
如何修改BarMenuInit和如何处理Item Where的初始化来达到如此一个目的?
当前系统语言设定是英语,而英语这个项在第2项位置,因此如何能做到当菜单进入语言选择时,反显位置就在英语那里?
1。修改BarMenuInit代码,处理第一次进入时的处理方式,也许就可以仅仅使用从子菜单退出时的处理方法
*/
//Bar型菜单初始化  公共部分
void BarMenuInit(void)
{
char Menu_i;          //计数变量 在菜单函数中用到
char Menu_j;          //计数变量
//-------------------
//比较"显示屏可以显示的项的数目(DispMax)"跟"需要显示的数目(ItemNum)"
//找出小者,以小者为显示上限
//例如显示屏可以显示3项,需要显示的项有2项,那么显示2项,有3项,显示3项,有4项的话,显示3项
    if (ItemNum > DispMax) {
        DispMin = DispMax;
    } else {
        DispMin = ItemNum;
    }
//--------------------
//    if (Flash) {//从父菜单进入 初始化
        if(Flash == FlashMode_AutoInit){//常规进入 做备份
            PUSH();//在修改Item Where之前备份这些参数数据!!
            Item = 0;
            Where = 0;
        } else if (Flash == FlashMode_ManualInit){    //非常规进入  在之前已经备份了,这里做边界检查
            if(Where > DispMin-1){//检查是否出界
                //Where = DispMin-1;//A.最底部的显示位置
                Where = 0;          //B.最顶部的显示位置
            }
            if(Item > ItemNum-1){//检查是否出界
                //Item = ItemNum-1;//A.最后的一个项
                Item = 0;          //B.最开始的一个项
            }
        }
//    }
//-------------------
//既然Item Where均是未定的,那么我们使用从子菜单退出的方法来找到应该再Where=0位置显示的Item项
//----------------
//方法2
    if (Item >= Where) {//未跨越零点
        Menu_j = Item -Where;
    } else {            //跨越零点
        Menu_j = ItemNum  - (Where - Item);
    }
    //此时Menu_J的值就是顶部(Where=0)显示的Item值
//----------------
    MenuGuiInit();

{   
    MenuShowBmp(MENU_BAR_BMP, 0, 0);
    //显示全部的子菜单项
    for (Menu_i = 0; Menu_i < DispMin; Menu_i++) {
        BarText(*(DispItem+Menu_j),BarXOffset,Menu_i*BarYSize+BarYOffset);
        if (Menu_j == Item){ //反显第Item项,位置是Where
            BarDisp(*(DispItem+Item),BarXOffset,Where*BarYSize+BarYOffset,1);
        } else {             //其它项 正常显示
            //BarDisp(*(DispItem+Menu_j),BarXOffset,Menu_i*BarYSize+BarYOffset,0);
        }
        if (Menu_j == (ItemNum-1)) {//到了最后一项,回环到最开始的一项
            Menu_j = 0;
        } else {                    //下一项
            Menu_j++;
        }
    }
    TitleBar(BarMenu->Name);
    ScrollBar(Item,ItemNum,Where,MenuBarNumPosX);                  //维护滚动条
 }
}
//Bar项菜单向左按键的行为
/*
可能的几种情况:
A.原有Bar的顶部,按键是向上,那么就需要刷新全部的显示
A1.若是需要显示的Bar多于单屏可以显示的Bar,那么重新显示全部
A2.若是需要显示的Bar不多于单屏可以显示的Bar,取消顶部高亮显示,高亮显示最后一项Bar
B.原有Bar不是在顶部,按键向上,那么取消原有Bar的高亮,高亮显示上一个Bar项
当然还需要维护:高亮显示的位置where/高亮显示Bar项的Item
*/

//维护Bar显示
void BarMenuBefore(void)
{
//    char Menu_i;          //计数变量 在菜单函数中用到
//    char Menu_j;          //计数变量
    char ItemBack;


    ItemBack = Item;//备份原有的Item,取消原有反显时需要使用
    //维护Item,得到需要反显的Item
    if (Item == 0) {
        Item = ItemNum-1;
        if (ItemNum > DispMax)
            Where = DispMax - 1;
        else 
            Where = ItemNum - 1;

        Jump2Menu(SelfMenuIndex,FlashMode_ReFlash);
        
        return;
    } else if (Where == 0) {
        Item --;
        Jump2Menu(SelfMenuIndex,FlashMode_ReFlash);
        return;
    } 
    
    Item--;
    
    //维护显示
    if (Where) {//当前位置不为0,就是说不是在顶部,两次反显

        //原来位置取消反显   项是ItemBack  位置Where
        BarDisp(*(DispItem+ItemBack),BarXOffset,(Where--)*BarYSize+BarYOffset,0);
        
        //上移后的位置反显   项是Item      位置Where-1 (Where--实现)
        BarDisp(*(DispItem+Item),BarXOffset,Where*BarYSize+BarYOffset,1);//高亮显示

        ScrollBar(Item,ItemNum, Where, MenuBarNumPosX);                  //维护滚动条

        Jump2Menu(SelfMenuIndex,FlashMode_NoAction);
  
    } 
     
}
//Bar项菜单向右按键的行为
//维护Bar显示
void BarMenuNext(void)
{
//    char Menu_i;          //计数变量 在菜单函数中用到
//    char Menu_j;          //计数变量
    char ItemBack;
    ItemBack = Item;
//---维护Item
    if (Item == (ItemNum-1)) {
        Item = 0;
        Where = 0;

        Jump2Menu(SelfMenuIndex,FlashMode_ReFlash);

        return;
    } else if (Where == DispMax-1) {
       Item++; 
       Jump2Menu(SelfMenuIndex,FlashMode_ReFlash);
       return;
    }
       
    Item++;

//---维护显示
 //   if (Where != (DispMin-1)) {//当前位置不为最末,两次反显



        //原来位置取消反显   项是ItemBack  位置Where
        BarDisp(*(DispItem+ItemBack),BarXOffset,(Where++)*BarYSize+BarYOffset,0);
        //下移后的位置反显   项是Item      位置Where+1(Where++实现)
        BarDisp(*(DispItem+Item),BarXOffset,Where*BarYSize+BarYOffset,1);//反显

        
        ScrollBar(Item,ItemNum,Where,MenuBarNumPosX);                  //维护滚动条

        Jump2Menu(SelfMenuIndex,FlashMode_NoAction);

        return;
  //  }
      
    
}




/*
********************************************************
********************************************************
*/
//-----------------------
//菜单备份函数
//备份当前菜单的各个参数
void PUSH(void)
{
    WhereBackup[WhereBackup_i++] = Where;      //备份Where--->高亮显示的位置
    ItemBackup[ItemBackup_i++] = Item;         //备份Item--->当前项的位置
    FatherIndex[Layer++] = KeyFuncIndex;      //备份KeyFuncIndex--->状态机的状态
//-------------------------------

//-------------------------------

}
//菜单还原函数
void POP(void)
{
    Layer--;      //先弹出一层,因为使用的是++,因此当前Layer指向下一个数组位置
    KeyFuncIndex = FatherIndex[Layer-1];     //恢复KeyFuncIndex
    Where = WhereBackup[--WhereBackup_i];    //恢复高亮显示位置Where
    Item = ItemBackup[--ItemBackup_i];       //恢复项位置Item
//-------------------------------
 
//-------------------------------
    Flash = FlashMode_ReFlash;                     //子项返回,请求刷新
}
//*********************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -