#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_used < RECORD_MAX_MSG_NUM) { mymemcpy(box->msgs[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; i < box->msg_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; }