在BREW中打造自己的GUI(6)-单选框与复选框的实现

来源:互联网 发布:新水浒q传源码 编辑:程序博客网 时间:2024/04/30 17:13
还有一个常用的UI控件是单选框与复选框。可惜BREW也不提供,所以,只能自己做一个了。

先看一下每个选项的结构定义,我们用图片来做那个选中和未选中的显示,这样才能做出更多更美观的界面效果,所以在结构中有两个成员pCkImage和pNrImage,同时,isSelected用来记录此项是否被选中:
typedef struct 
{
    
int          nItemID;
    AECHAR    
* pText;

    IImage    
* pCkImage;
    IImage    
* pNrImage;

    
const char    * pszResFile;
    uint16        wCkImage;
    uint16        wNrImage;    

    boolean        isSelected;
}
 TGBOption;
 而整个控件的结构如下:
struct _IGButton {
    
    
const AEEVTBL(IGButton) * pvt;

    uint32          m_nRefs;    
    IShell            
*m_pIShell;
    IDisplay        
*m_pIDisplay;
    IModule            
*m_pIModule;

    boolean            m_isActive;
    AEERect            m_Rect;    

    uint32            props;

    AECHAR            
*pTitle;
    AEEFont            titleFont;
    RGBVAL            titleColor;

    IImage            
*pBkImage;

    TQueueList        
*pOptionList;
    
int                m_Index;

}
;
同样是用 TQueueList来保存一个选项的链表,当前少不了m_Index当前项了。

需要的接口函数定义如下:
AEEINTERFACE(IGButton)
{
    DECLARE_IBASE(IGButton)

    DECLARE_ICONTROL(IGButton)

    boolean     (
*SetTitle)            (IGButton * po, AECHAR * szText,AEEFont font,RGBVAL color);
    boolean     (
*SetBkImage)        (IGButton * po, IImage * img);
    boolean        (
*AddOption)        (IGButton * po, TGBOption *opt);
    boolean        (
*IsChecked)        (IGButton * po,int idx);
    
int            (*GetSel)            (IGButton * po);
    
int            (*GetItemCount)        (IGButton * po);
    
}
;

下面来看看实现,同样的先看HandleEvent,需要处理上下方向键,修改m_Index以改变当前项;处理SELECT键处理选中/取消选中的操作。

在Redraw函数中呢?遍历一下那个pOptionList链表,根据每个项是否选中,绘制出来即可。
static boolean IGButton_Redraw(IGButton * pMe)
{
    
int i,j,height,h,a,b;
    
int xx,yy,dxx,dyy;
    AEERect rec;
    AEEImageInfo infIc;
    RGBVAL oldColor;
    
    TQueueList 
* p = pMe->pOptionList;
    
    h
=IDISPLAY_GetFontMetrics(pMe->m_pIDisplay,AEE_FONT_NORMAL,&a,&b);
        
    IDISPLAY_EraseRect(pMe
->m_pIDisplay,&pMe->m_Rect);

    
if(pMe->pBkImage)
    
{
        IIMAGE_SetDrawSize(pMe
->pBkImage,pMe->m_Rect.dx,pMe->m_Rect.dy);
        IIMAGE_Draw(pMe
->pBkImage,pMe->m_Rect.x,pMe->m_Rect.y);
    }

        
    oldColor 
= IDISPLAY_SetColor(pMe->m_pIDisplay,CLR_USER_TEXT,MAKE_RGB(0,0,0));

    i
=0;
    height
=pMe->m_Rect.y;
    
while(p)
    
{
        IImage 
* img;
        TGBOption 
* pData=(TGBOption*)p->pData;

        
if(pData->isSelected)
            img
=pData->pCkImage;
        
else
            img
=pData->pNrImage;
            
        ZEROAT(
&infIc);
        
if(img)
        
{
            IIMAGE_GetInfo(img,
&infIc);
            IIMAGE_Draw(img,pMe
->m_Rect.x,height);
        }

        
        xx
=pMe->m_Rect.x+infIc.cx;
        yy
=height+(infIc.cy-h)/2;
        dxx
=pMe->m_Rect.x+pMe->m_Rect.dx-xx;
        dyy
=h;
        SETAEERECT(
&rec,xx,yy,dxx,dyy);        
        IDISPLAY_DrawText(pMe
->m_pIDisplay,AEE_FONT_NORMAL,pData->pText,-1,xx,yy,&rec,IDF_TEXT_TRANSPARENT);

        
if(i==pMe->m_Index)
        
{
            xx
=pMe->m_Rect.x;
            yy
=height;
            dxx
=infIc.cx+IDISPLAY_MeasureText(pMe->m_pIDisplay,AEE_FONT_NORMAL,pData->pText);;
            dyy
=infIc.cy;
            SETAEERECT(
&rec,xx,yy,dxx,dyy);    

            IDISPLAY_DrawRect(pMe
->m_pIDisplay,&rec,MAKE_RGB(0,0,250),0,IDF_RECT_FRAME);
        }

            
        height
+=infIc.cy;

        p
=p->pNext;
        i
++;

    }


       
    IDISPLAY_Update(pMe
->m_pIDisplay);
    IDISPLAY_SetColor(pMe
->m_pIDisplay,CLR_USER_TEXT,oldColor);    

    
return TRUE;
}

还有一件事,如果在程序中取到这个组件的结果呢?如果是单选就可以直接GetSel了,如果是复选则循环一下一个个判断是否选中IsChecked即可:
static boolean IGButton_IsChecked(IGButton * pMe,int idx)
{
    
if(pMe->props&0x01==GBTN_STYLE_CHECK)
    
{
        TGBOption 
* pData=(TGBOption*)Queue_Get(pMe->pOptionList,idx);
        
if(pData)
        
{
            
return pData->isSelected;
        }
        
    }

    
return FALSE;
}

static int    IGButton_GetSel(IGButton * pMe)
{
    
if((pMe->props&0x01)==GBTN_STYLE_RADIO)
    
{
        TQueueList 
* p=pMe->pOptionList;
        
//int i = 0;
        while(p)
        
{
            TGBOption 
* pData=(TGBOption*)p->pData;
            
if(pData && pData->isSelected)
                
return pData->nItemID;
            
//i+=1;
            p=p->pNext;            
        }

    }

    
return -1;
}

OK,基本上搞定。
原创粉丝点击