您的位置:首页 > 产品设计 > UI/UE

在BREW中打造自己的GUI(4)-IGStatic的实现

2008-03-04 12:18 519 查看
BREW中的IStatic可以方便地显示一个文本,但是它没有背景不能滚动,其实并不方便,所以我们也自己做一个吧。

首先,同样是定义它的数据结构如下:




struct _IGStatic ...{




const AEEVTBL(IGStatic) * pvt;




uint32 m_nRefs;


IShell *m_pIShell;


IDisplay *m_pIDisplay;


IModule *m_pIModule;




boolean m_isActive;


AEERect m_Rect;




int cntLines; //一屏可显示的行数


int nTopLine; //当前显示的首行




int nScrollTop; //滚动的首行


int nScrollBtm; //滚动的末行


int nLineHeight; //行高




IImage *pImage; //背景图


RGBVAL color; //文字颜色


AEEFont font; //文字字体




int lineCount; //总行数


int nNext; //当前


AECHAR **ppLines; //分行保存的字串内容




IGScrollBar * pScBar;




uint32 props;




};

除了背景图、文字颜色字体以外,我们主要考虑是的如何实现文本的分行?如何实现文本的上下滚动?所以,在这里增加了几个辅助变量来处理行数。

需要额外增加的接口函数并不多,就是设置一个文本和图片罢了:


AEEINTERFACE(IGStatic)




...{


DECLARE_IBASE(IGStatic)




DECLARE_ICONTROL(IGStatic)




boolean (*SetText) (IGStatic * po, AECHAR * szText,AEEFont font,RGBVAL color);


boolean (*SetImage) (IGStatic * po, IImage * img);




};

实现的关键在于一是文本的分行处理,在setText的时候,我们需要完成这件事,计算文本的长度,循环切割它判断是否可以在当前的mRect范围内显示,直到可以的话,则将这段文本作为一行放入ppLines中:


static boolean IGStatic_SetText(IGStatic * pMe, AECHAR * szText,AEEFont font,RGBVAL color)




...{


AECHAR sch;


AECHAR * p;


int k,len;




pMe->nNext=0;




pMe->color=color;


pMe->font=font;


pMe->nLineHeight=IDISPLAY_GetFontMetrics (pMe->m_pIDisplay, pMe->font,NULL,NULL);


pMe->cntLines=(pMe->m_Rect.dy-MARGIN*2)/pMe->nLineHeight;




p=szText;


do




...{


k=WSTRLEN(p);


if(k>0)




...{


len=IDISPLAY_MeasureText(pMe->m_pIDisplay,pMe->font,p);


while(len>pMe->m_Rect.dx-MARGIN*2)




...{


k--;


sch=p[k];p[k]=0;


len=IDISPLAY_MeasureText(pMe->m_pIDisplay,pMe->font,p);


p[k]=sch;


}


pMe->ppLines=(AECHAR**)REALLOC(pMe->ppLines,sizeof(AECHAR*)*(pMe->nNext+1));


_AppendLine(pMe,p,k);


p+=k;


}


}while(k>0);




pMe->lineCount=pMe->nNext;




if(pMe->pScBar)


IGSCROLLBAR_SetRange(pMe->pScBar,0,pMe->lineCount);




return TRUE;


}

在正确地分行以后,剩下的事情就好做了,在HandleEvent时处理一下当前行,实现上下滚动。在Redraw时根据当前行、当前页的首行、每页可显示行数就可以正确地显示文本了。


static boolean IGStatic_Redraw(IGStatic * pMe)




...{


//if(pMe->m_isActive)




...{


RGBVAL oc;


int i=0,j=0;


int nMax = (pMe->lineCount-pMe->nTopLine<pMe->cntLines)?pMe->lineCount-pMe->nTopLine:pMe->cntLines;




IDISPLAY_EraseRect(pMe->m_pIDisplay,&pMe->m_Rect);




if(pMe->pImage)




...{


IIMAGE_SetDrawSize(pMe->pImage,pMe->m_Rect.dx,pMe->m_Rect.dy);


IIMAGE_Draw(pMe->pImage,pMe->m_Rect.x,pMe->m_Rect.y);


}




if(pMe->props&0x02)


IDISPLAY_DrawRect(pMe->m_pIDisplay,&pMe->m_Rect,MAKE_RGB(0,0,0),-1,IDF_RECT_FRAME);




oc=IDISPLAY_SetColor(pMe->m_pIDisplay,CLR_USER_TEXT,pMe->color);


for ( i=0,j=pMe->nTopLine; i<nMax; i++,j++)


_DrawLine(pMe,j,i);




if(pMe->pScBar && pMe->props&0x01)




...{


IGSCROLLBAR_SetPosition(pMe->pScBar,pMe->nTopLine,pMe->cntLines);


IGSCROLLBAR_Redraw(pMe->pScBar);


}




IDISPLAY_Update(pMe->m_pIDisplay);


IDISPLAY_SetColor(pMe->m_pIDisplay,CLR_USER_TEXT,oc);


}




return TRUE;


}

你可能会注意到这里我们还有一个控件IGScrollBar,是我们自定义的滚动条组件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: