#include "mywin_inc.h" WIN_RecordStruct *WIN_CreatRecord (WIN_WindowStruct *base, void (*msgLoop)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg), int x,int y,int x_size,int y_size) { //重设消息循环 if (msgLoop==0) { msgLoop=(void (*)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg))RECORD_DefaultMsgLoop; } WIN_RecordStruct *ret=mymalloc (sizeof ( WIN_RecordStruct)); //调用父类的构造函数 if (ret) { mymemset (ret,0,sizeof ( WIN_RecordStruct)); if (0==WIN_CreatWindowExt((WIN_WindowStruct *)ret,base,msgLoop,x,y,x_size,y_size)) { //创建失败 myfree (ret); ret=0; } else { //构造一个 ((WIN_WindowStruct *)ret)->winType="WIN_RecordStruct"; ((WIN_WindowStruct *)ret)->bkcolor=0x0; ((WIN_WindowStruct *)ret)->color=0xffffaa; ((WIN_WindowStruct *)ret)->keyChid=1; //作为子窗口被创建 ret->color_light=0xffffff; ret->color_dark=0x808080; ret->msg_x_size=x_size*4/5; //每条消息的最大显示宽度 ret->font_size=16; //默认字体大小 } } return ret; } //得到消息总长度 int RECORD_GetMsgYSize(WIN_RecordStruct *box); //添加消息,msg_type='s',发送的消息,msg_type='r',接收的消息 int RECORD_AddMsg(WIN_RecordStruct *box,char msg_type,char *msg) { int len=strlen(msg)+1; if(len>=RECORD_MAX_MSG_LEN) return -1; if (box->msg_usedmsgs[box->msg_end].msg,msg,len); box->msgs[box->msg_end].msg_type=msg_type; box->msg_used++; } else { mymemcpy(box->msgs[box->msg_end].msg,msg,len); box->msgs[box->msg_end].msg_type=msg_type; box->msg_start++; if (box->msg_start>=RECORD_MAX_MSG_NUM) box->msg_start=0; } //得到文字框的大小 int txt_x_size=len*box->font_size/2; box->msgs[box->msg_end].x_size=txt_x_size; box->msgs[box->msg_end].y_size=box->font_size; while(txt_x_size>box->msg_x_size) { txt_x_size-=box->msg_x_size; box->msgs[box->msg_end].y_size+=box->font_size; } if(box->msgs[box->msg_end].x_size>box->msg_x_size) box->msgs[box->msg_end].x_size=box->msg_x_size; box->msgs[box->msg_end].y_size+=8; //更新尾部指针 box->msg_end++; if (box->msg_end>=RECORD_MAX_MSG_NUM) box->msg_end=0; //显示最新的消息 int all_y_size=RECORD_GetMsgYSize(box); if(all_y_size>((WIN_WindowStruct *)box)->y_size) { box->y_off=((WIN_WindowStruct *)box)->y_size-all_y_size; } //父窗口是顶端窗口时刷新 // if (WIN_FindTopWin(WIN_GetBaseWindow())==((WIN_WindowStruct *)box)->baseWin) { WIN_SetInvalidWhenTop ((WIN_WindowStruct *)box); } return 0; } //得到消息总长度 int RECORD_GetMsgYSize(WIN_RecordStruct *box) { int y_size=0; for (int i=0;imsg_used;i++) { y_size+=box->msgs[i].y_size; } return y_size; } //由相对与box->msg_start的索引偏移值得到消息结构体 Record_MsgStruct *RECORD_GetMsgByIndexOffset(WIN_RecordStruct *box,int index_offset) { if(index_offset>box->msg_used-1) return 0; if(index_offset<-box->msg_used) return 0; int index=0; if (index_offset>=0) index=box->msg_start; if (index_offset<0) index=box->msg_end; return &box->msgs[ (index+index_offset)%box->msg_used]; } //由偏移值得到消息索引偏移 int RECORD_GetMsgIndexOffsetByOffset(WIN_RecordStruct *box,int offset,int *box_offset) { int msg_y_size=RECORD_GetMsgYSize(box); int y_size=((WIN_WindowStruct *)box)->y_size; if(msg_y_size+offset<0) return -1; //偏移值大于本身长度,找不到索引 if(offset>0) return -1; int sum_y_size=0; int index=0; while(1) { Record_MsgStruct *msg=RECORD_GetMsgByIndexOffset(box,index); if (msg==0) return -1; //参数有误,找不到消息 sum_y_size+=msg->y_size; if (offset+sum_y_size<0) index++; else { *box_offset=offset+sum_y_size-msg->y_size; break; } } return index; } void RECORD_DefaultPaint (WIN_RecordStruct *box) { int x=0; int y=0; int x_size=((WIN_WindowStruct *)box)->x_size; int y_size=((WIN_WindowStruct *)box)->y_size; WIN_PaintBackGround ((WIN_WindowStruct *)box); u32 font_size=WIN_SetFontSize(box->font_size); WIN_SetLcdColor (((WIN_WindowStruct *)box)->color); int box_off=0; int index=RECORD_GetMsgIndexOffsetByOffset(box,box->y_off,&box_off); if (index!=-1) { while(1) { Record_MsgStruct *msg=RECORD_GetMsgByIndexOffset(box,index); if (msg) { if (msg->msg_type=='r') { WIN_SetLcdColor (((WIN_WindowStruct *)box)->color); WIN_DrawTxtAtRect(msg->msg,2,box_off+1,msg->x_size,msg->y_size-6); WIN_SetLcdColor (((WIN_WindowStruct *)box)->bkcolor); //WIN_DrawRect (0,box_off,msg->x_size,msg->y_size-3); WIN_FillRectByColorAlpha(0,box_off,msg->x_size,msg->y_size-3,16); } else if (msg->msg_type=='s') { WIN_SetLcdColor (((WIN_WindowStruct *)box)->color); WIN_DrawTxtAtRect(msg->msg,x_size+2-msg->x_size,box_off+1,msg->x_size,msg->y_size-6); WIN_SetLcdColor (((WIN_WindowStruct *)box)->bkcolor); //WIN_DrawRect (x_size-msg->x_size,box_off,msg->x_size,msg->y_size-3); WIN_FillRectByColorAlpha(x_size-msg->x_size,box_off,msg->x_size,msg->y_size-3,16); } box_off+=msg->y_size; } else break; index++; if (box_off>y_size) break; } } //绘制边框 if (box->press) WIN_SetLcdColor (box->color_light); else WIN_SetLcdColor (box->color_dark); WIN_DrawRect (0,0,((WIN_WindowStruct *)box)->x_size,((WIN_WindowStruct *)box)->y_size); WIN_SetFontSize(font_size); } void RECORD_DefaultMsgLoop (WIN_RecordStruct *box,WIN_MsgStruct *msg) { WIN_MoveStruct *m=0; WIN_KeyStruct *k=0; switch (msg->msg) { case WIN_MSG_PAINT: RECORD_DefaultPaint(box); break; case WIN_MSG_KEY: k=msg->data.p; if (k->shortPress& KEY_VALUE_DOWN) { } else if (k->shortPress&KEY_VALUE_UP) { } break; case WIN_MSG_MOVE: m=msg->data.p; switch (m->moveType) { case MOVE_DATA_MOVED: { box->y_off+=m->y_move; int msg_y_size=RECORD_GetMsgYSize(box); if (box->y_off>0) box->y_off=0; else if(box->y_off<-msg_y_size) box->y_off=-msg_y_size; WIN_SetInvalid ((WIN_WindowStruct *)box); break; } case MOVE_DATA_TOUCHIN: box->press=1; WIN_SetInvalid ((WIN_WindowStruct *)box); break; case MOVE_DATA_TOUCHOUT: case MOVE_DATA_MOVEOUT: box->press=0; WIN_SetInvalid ((WIN_WindowStruct *)box); break; default: break; } break; default: WIN_DefaultMsgLoop((WIN_WindowStruct *)box,msg); break; } } WIN_RecordStruct *RECORD_DrawRecord (WIN_WindowStruct *base,int x,int y,int x_size,int y_size) { WIN_RecordStruct *box=WIN_CreatRecord(base,0,x,y,x_size,y_size); //设置弹出框的背景 WIN_SetBackPic ((WIN_WindowStruct *)box); WIN_ShowWindow((WIN_WindowStruct *)box); return box; }