Files
player/Project/Src/MyWin/Window/mywin_scrollbar.c
2025-07-06 18:46:13 +08:00

288 lines
9.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}