Files
player/Project/Src/MyWin/Window/mywin_scrollbar.c

336 lines
7.7 KiB
C
Raw Permalink Normal View History

2025-06-27 00:32:57 +08:00
#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;
}