#include "mywin_inc.h" #define WIN_SCROLLBAR_TYPE "WIN_ScrollbarStruct" void SCROLLBAR_Delete(WIN_ScrollbarStruct *bar); WIN_ScrollbarStruct *WIN_CreatScrollbar( 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))SCROLLBAR_DefaultMsgLoop; } WIN_ScrollbarStruct *ret = mymalloc(sizeof(WIN_ScrollbarStruct)); // 调用父类的构造函数 if (ret) { mymemset(ret, 0, sizeof(WIN_ScrollbarStruct)); if (0 == WIN_CreatWindowExt((WIN_WindowStruct *)ret, base, msgLoop, x, y, x_size, y_size)) { // 创建失败 myfree(ret); ret = 0; } else { // 构造一个 ((WIN_WindowStruct *)ret)->deleteWindow = (void (*)(struct _WIN_WindowStruct *win))SCROLLBAR_Delete; ((WIN_WindowStruct *)ret)->winType = WIN_SCROLLBAR_TYPE; ((WIN_WindowStruct *)ret)->bkcolor = 0x342f2a; ((WIN_WindowStruct *)ret)->color = 0xc2ae9b; ((WIN_WindowStruct *)ret)->keyChid = 1; // 作为子窗口被创建 ret->color_light = 0xffffff; ret->color_dark = 0x808080; ret->y_step = 45; } } return ret; } void SCROLLBAR_Delete(WIN_ScrollbarStruct *bar) { if (bar->items) myfree(bar->items); // 调用父类的销毁函数 WIN_DeleteWindow((WIN_WindowStruct *)bar); } void SCROLLBAR_AddItem(WIN_ScrollbarStruct *bar, char *item, char *pic_path) { if (bar->itemNum < bar->itemMaxNum) { int len = strlen(item); if (len + 1 > SCROLLBAR_ITEM_MAXLEN) printf("%s:item txt to long\r\n", __func__); mymemcpy(bar->items[bar->itemNum].txt, item, len + 1); bar->items[bar->itemNum].pic_path = pic_path; bar->itemNum++; } } Scrollbar_ItemStruct *SCROLLBAR_GetItemByOffset(WIN_ScrollbarStruct *bar, int offset) { if (bar->itemNum == 0) return 0; while (bar->index + offset < 0) offset += bar->itemNum; while (bar->index + offset >= bar->itemNum) offset -= bar->itemNum; if ((bar->index + offset >= 0) && (bar->index + offset < bar->itemNum)) return &bar->items[bar->index + offset]; else return 0; } // 绘制一个条目,y是条目中心坐标 void SCROLLBAR_DrawItem(WIN_ScrollbarStruct *bar, int offset, int y) { Scrollbar_ItemStruct *item = SCROLLBAR_GetItemByOffset(bar, offset); int x = ((WIN_WindowStruct *)bar)->x_size / 2; if (item) { if (offset == 0) WIN_SetLcdColor(bar->color_light); else WIN_SetLcdColor(bar->color_dark); WIN_PicStruct *pic = WIN_GetPic(item->pic_path); int pic_xsize = 0; if (pic) pic_xsize = pic->xsize + WIN_GetFontWidth() / 2; int xsize = strlen(item->txt) * WIN_GetFontWidth() / 2 + pic_xsize; x = x - xsize / 2; WIN_DrawPic(pic, x, y - pic->ysize / 2, pic->xsize, pic->ysize); x += pic_xsize; WIN_DrawTxtAt(item->txt, x, y - WIN_GetFontHight() / 2); } } // 默认绘制函数 void SCROLLBAR_DefaultPaint(WIN_ScrollbarStruct *bar) { int x = 0; int y = 0; int x_size = ((WIN_WindowStruct *)bar)->x_size; int y_size = ((WIN_WindowStruct *)bar)->y_size; WIN_PaintBackGround((WIN_WindowStruct *)bar); int draw_item_num = 3; for (; draw_item_num * bar->y_step < y_size; draw_item_num += 2) { } for (int i = -draw_item_num / 2; i < draw_item_num / 2 + 1; i++) { SCROLLBAR_DrawItem(bar, i, bar->y_step * i + y_size / 2 + bar->y_offset); } } // 惯性定时器消息 int SCROLLBAR_TimerInertia(WIN_ScrollbarStruct *bar) { if (bar->x_inertia > 0) bar->x_inertia--; else if (bar->x_inertia < 0) bar->x_inertia++; if (bar->y_inertia > 0) bar->y_inertia--; else if (bar->y_inertia < 0) bar->y_inertia++; // 惯性滑动 WIN_SendTouchMove((WIN_WindowStruct *)bar, bar->x_inertia, bar->y_inertia); if (bar->y_inertia == 0 && bar->x_inertia == 0) { WIN_DeleteTimer(bar->timer_inertia); bar->timer_inertia = 0; bar->num_inertia = 0; } return 0; } #define SCROLLBAR_INDEX_ADD() \ { \ if (bar->index < bar->itemNum - 1) \ bar->index++; \ else \ bar->index = 0; \ } #define SCROLLBAR_INDEX_SUB() \ { \ if (bar->index > 0) \ bar->index--; \ else \ bar->index = bar->itemNum - 1; \ } void SCROLLBAR_DefaultMsgLoop(WIN_ScrollbarStruct *bar, WIN_MsgStruct *msg) { WIN_MoveStruct *m = 0; WIN_KeyStruct *k = 0; switch (msg->msg) { case WIN_MSG_PAINT: SCROLLBAR_DefaultPaint(bar); break; case WIN_MSG_INIT: WIN_SetBackPic((WIN_WindowStruct *)bar); break; case WIN_MSG_KEY: k = msg->data.p; if (k->shortPress & KEY_VALUE_DOWN) { SCROLLBAR_INDEX_ADD(); bar->y_offset = 0; WIN_SetInvalid((WIN_WindowStruct *)bar); } else if (k->shortPress & KEY_VALUE_UP) { SCROLLBAR_INDEX_SUB(); bar->y_offset = 0; WIN_SetInvalid((WIN_WindowStruct *)bar); } break; case WIN_MSG_MOVE: m = msg->data.p; switch (m->moveType) { case MOVE_DATA_MOVED: bar->y_offset += m->y_move; if (bar->y_offset > bar->y_step / 2) { bar->y_offset -= bar->y_step; SCROLLBAR_INDEX_SUB(); } else if (bar->y_offset <= -bar->y_step / 2) { bar->y_offset += bar->y_step; SCROLLBAR_INDEX_ADD(); } if (bar->timer_inertia == 0) { // 存储惯性值 // bar->x_inertia=bar->x_inertia*bar->num_inertia+ // m->x_move; // bar->y_inertia=bar->y_inertia*bar->num_inertia+ m->y_move; // bar->num_inertia++; // bar->x_inertia/=bar->num_inertia; // bar->y_inertia/=bar->num_inertia; bar->x_inertia = m->x_move; bar->y_inertia = m->y_move; } if (bar->x_inertia == 0 && bar->y_inertia == 0) bar->y_offset = 0; WIN_SetInvalidWhenTop((WIN_WindowStruct *)bar); break; case MOVE_DATA_SHORT: if (bar->timer_inertia == 0) { WIN_SendMsgToPrent((WIN_WindowStruct *)bar, CHID_USER, SCROLLBAR_PRESSED); } else { WIN_DeleteTimer(bar->timer_inertia); bar->timer_inertia = 0; bar->x_inertia = 0; bar->y_inertia = 0; } break; case MOVE_DATA_TOUCHOUT: case MOVE_DATA_MOVEOUT: // 添加惯性定时器 if ((bar->timer_inertia == 0) && (bar->x_inertia || bar->y_inertia)) { bar->timer_inertia = WIN_CreatTimer((WIN_WindowStruct *)bar, 20); } else if (bar->timer_inertia == 0) { // 滑动停止 // WIN_SendTouchMove((WIN_WindowStruct //*)bar,0,0); } default: break; } break; case WIN_MSG_TIMER: if (msg->data.v == bar->timer_inertia) { SCROLLBAR_TimerInertia(bar); } break; default: WIN_DefaultMsgLoop((WIN_WindowStruct *)bar, msg); break; } } void SCROLLBAR_SetItemNum(WIN_ScrollbarStruct *bar, int itemNum) { if (bar->items) { bar->items = myrealloc(bar->items, sizeof(Scrollbar_ItemStruct) * itemNum); if (itemNum > bar->itemMaxNum) mymemset(bar->items + bar->itemMaxNum * sizeof(Scrollbar_ItemStruct), 0, sizeof(Scrollbar_ItemStruct) * (itemNum - bar->itemMaxNum)); } else { bar->items = mymalloc(sizeof(Scrollbar_ItemStruct) * itemNum); mymemset(bar->items, 0, sizeof(Scrollbar_ItemStruct) * itemNum); } bar->itemMaxNum = itemNum; } WIN_ScrollbarStruct *SCROLLBAR_SelectItem(WIN_WindowStruct *base, char **item, int itemNum, int x, int y, int x_size, int y_size) { WIN_ScrollbarStruct *bar = WIN_CreatScrollbar(base, 0, x, y, x_size, y_size); SCROLLBAR_SetItemNum(bar, itemNum); for (int i = 0; i < itemNum; i++) { int len = strlen(item[i]); SCROLLBAR_AddItem(bar, item[i], 0); if (x_size < len) x_size = len; } // 设置弹出框的背景 WIN_SetBackPic((WIN_WindowStruct *)bar); WIN_ShowWindow((WIN_WindowStruct *)bar); return bar; } WIN_ScrollbarStruct *SCROLLBAR_SelectNum(WIN_WindowStruct *base, int min, int max, int x, int y, int x_size, int y_size) { // if (max-min+1>bar->itemMaxNum) return 0; if (max < min) return 0; char **item = mymalloc((max - min + 1) * sizeof(char **)); for (int i = 0; i < max - min + 1; i++) { item[i] = mymalloc(SCROLLBAR_ITEM_MAXLEN * sizeof(char)); sprintf(item[i], "%d", min + i); } WIN_ScrollbarStruct *ret = SCROLLBAR_SelectItem(base, item, max - min + 1, x, y, x_size, y_size); for (int i = 0; i < max - min + 1; i++) { myfree(item[i]); } myfree(item); return ret; }