Files
player/Project_App_MusicPlayer/App_Src/win/mywin_user_picmenu.c

385 lines
8.7 KiB
C
Raw Permalink Normal View History

2025-06-27 00:32:57 +08:00
#include "mywin_inc.h"
#include "png.h"
#include <zlib.h>
#include "mywin_user_picmenu.h"
void PICMENU_Delete(WIN_PicMenuStruct *menu);
WIN_PicMenuStruct *WIN_CreatPicMenu (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))PICMENU_DefaultMsgLoop;
}
WIN_PicMenuStruct *ret=mymalloc (sizeof ( WIN_PicMenuStruct));
//调用父类的构造函数
if (ret)
{
mymemset (ret,0,sizeof ( WIN_PicMenuStruct));
if (0==WIN_CreatTouchEx((WIN_TouchWinStruct *)ret,base,msgLoop,x,y,x_size,y_size))
{
//创建失败
myfree (ret);
ret=0;
}
else
{
((WIN_WindowStruct *)ret)->deleteWindow=(void (*)(struct _WIN_WindowStruct *win))PICMENU_Delete;
((WIN_WindowStruct *)ret)->winType="WIN_PicMenuStruct";
((WIN_WindowStruct *)ret)->color=0xaabbcc;
//构造一个
ret->y_step=80;
ret->timer_anim=WIN_CreatTimer((WIN_WindowStruct *)ret,20);
}
}
return ret;
}
void PICMENU_Delete(WIN_PicMenuStruct *menu)
{
//释放条目申请的内存
for(int i=0;i<menu->allItemNum;i++)
{
PICMENU_ItemStruct *item=&menu->item[i];
if(item->img.data) myfree(item->img.data);
if(item->img_min.data) myfree(item->img_min.data);
GIF_DecodeStructFree (&item->img_gif);
}
//调用父类的销毁函数
WIN_DeleteWindow ( (WIN_WindowStruct *)menu);
}
//解码png图片成功返回1失败返回0
static int decode_png(WIN_PicStruct *pic,char *name)
{
int png_err=0;
png_image image; /* The control structure used by libpng */
/* Initialize the 'png_image' structure. */
memset(&image, 0, (sizeof image));
image.version = PNG_IMAGE_VERSION;
/* The first argument is the file to read: */
if (png_image_begin_read_from_file(&image, name) != 0)
{
image.format = PNG_FORMAT_BGRA;
pic->data = mymalloc(PNG_IMAGE_SIZE(image));
pic->format=PIC_FORMAT_ARGB8888;
pic->xsize=image.width;
pic->ysize=image.height;
if (
png_err=png_image_finish_read(&image, NULL/*background*/, pic->data,
0/*row_stride*/, NULL/*colormap*/),png_err != 0)
{
return 1;
}
else
{
myfree(pic->data);
return 0;
}
}
return 0;
}
//图像缩放
static int pic_zoom (WIN_PicStruct *dst,WIN_PicStruct *src)
{
if(src==0||dst==0) return 0;
if(src->xsize==0||src->ysize==0||dst->xsize==0||dst->ysize==0) return 0;
if(src->data==0||dst->data==0) return 0;
if(src->format!=PIC_FORMAT_ARGB8888||dst->format!=PIC_FORMAT_ARGB8888) return 0;
u32 *src_dat=(u32 *)src->data;
u32 *dst_dat=(u32 *)dst->data;
for (int y=0;y<dst->ysize;y++)
{
for (int x=0;x<dst->xsize;x++)
{
int src_x=(x*src->xsize/dst->xsize);
int src_y=(y*src->ysize/dst->ysize);
dst_dat[y*dst->xsize+x]=src_dat[src_y*src->xsize+src_x];
}
}
return 1;
}
//设置条目
void PICMENU_AddItem (WIN_PicMenuStruct *menu,char *img_name,char *gif_name,char *txt,WIN_TouchWinStruct *(*creat)(WIN_TouchWinStruct *))
{
if(menu->allItemNum<MENU_ITEM_MAXNUM)
{
if(decode_png(&menu->item[menu->allItemNum].img,img_name))
{
WIN_PicStruct *src=&menu->item[menu->allItemNum].img;
WIN_PicStruct *dst=&menu->item[menu->allItemNum].img_min;
dst->format=PIC_FORMAT_ARGB8888;
dst->xsize=src->xsize*3/4;
dst->ysize=src->ysize*3/4;
dst->data=mymalloc(dst->xsize*dst->ysize*4);
pic_zoom(dst,src);
}
GIF_Decode(&menu->item[menu->allItemNum].img_gif,(u8*)gif_name);
mymemcpy(&menu->item[menu->allItemNum].txt,txt,strlen(txt)+1);
if(creat) menu->item[menu->allItemNum].creat=creat;
menu->allItemNum++;
}
}
//根据条目偏移找到对应条目
PICMENU_ItemStruct *PICMENU_GetItemByOffset (WIN_PicMenuStruct *menu,int offset)
{
while(menu->index+offset<0) offset+=menu->allItemNum;
while(menu->index+offset>=menu->allItemNum) offset-=menu->allItemNum;
if((menu->index+offset>=0)&&(menu->index+offset<menu->allItemNum))
return &menu->item[menu->index+offset];
else
return 0;
}
//根据偏移显示条目
void PICMENU_DrawItem(WIN_PicMenuStruct *menu,int offset,int y)
{
PICMENU_ItemStruct *item=PICMENU_GetItemByOffset(menu,offset);
int x=((WIN_WindowStruct *)menu)->x_size/4;
if (item)
{
//显示小图标
WIN_PicStruct *pic=&item->img_min;
if (offset==0)
{
pic=&item->img;
}
WIN_FillRectAlpha(x-pic->xsize/2,y-pic->ysize/2,pic->xsize,pic->ysize,pic->data,0,0,pic->xsize,pic->ysize);
if(offset==0)
{
//显示动画大图
x=((WIN_WindowStruct *)menu)->x_size*3/4;
GIF_DecodeStruct *gif=&item->img_gif;
WIN_PicStruct gif_pic={0};
gif_pic.data=gif->frame[item->frameNow];
gif_pic.xsize=gif->x_size;
gif_pic.ysize=gif->y_size;
pic=&gif_pic;
WIN_FillRect(x-pic->xsize/2,y-pic->ysize/2,pic->xsize,pic->ysize,pic->data,0,0,pic->xsize,pic->ysize);
//显示字符
WIN_SetLcdColor(((WIN_WindowStruct *)menu)->color);
WIN_DrawTxtHCenterAt(item->txt,x,y+pic->ysize/2+6);
}
}
}
void PICMENU_Paint(WIN_PicMenuStruct *menu)
{
int x=0;
int y=0;
int x_size=((WIN_WindowStruct *)menu)->x_size;
int y_size=((WIN_WindowStruct *)menu)->y_size;
WIN_PaintBackGround ((WIN_WindowStruct *)menu);
int draw_item_num=2;
for (;draw_item_num*menu->y_step<y_size;draw_item_num+=2){}
for (int i=draw_item_num;i>=0;i--)
{
//调整顺序,边上的先显示,中间的后显示
if(i!=0)
{
PICMENU_DrawItem(menu,i,menu->y_step*i+y_size/2+menu->move_yoff);
PICMENU_DrawItem(menu,-i,menu->y_step*(-i)+y_size/2+menu->move_yoff);
}
else
{
PICMENU_DrawItem(menu,i,menu->y_step*i+y_size/2+menu->move_yoff);
}
}
}
#define PICMENU_INDEX_ADD() {if (menu->index<menu->allItemNum-1) menu->index++;\
else menu->index=0;PICMENU_SetChildEnter(menu);}
#define PICMENU_INDEX_SUB() {if (menu->index>0) menu->index--;\
else menu->index=menu->allItemNum-1;PICMENU_SetChildEnter(menu);}
//设置滑动进入的子窗口
int PICMENU_SetChildEnter(WIN_PicMenuStruct *menu)
{
WIN_TouchWinStruct *touch=(WIN_TouchWinStruct *)menu;
WIN_WindowStruct *win=(WIN_WindowStruct *)menu;
//有个问题如果创建函数没有界面这个滑动操作就会出bug暂时屏蔽
// TOUCHWIN_ClearChild(touch);
// TOUCHWIN_AddChild(touch,TOUCH_CON_LEFT_PAR(win->x_size,win->y_size,menu->item[menu->index].creat));
return 1;
}
//默认消息处理函数
void PICMENU_DefaultMsgLoop (WIN_PicMenuStruct *menu,WIN_MsgStruct *msg)
{
WIN_MoveStruct *m=0;
WIN_KeyStruct *k=0;
switch (msg->msg)
{
case WIN_MSG_PAINT:
PICMENU_Paint(menu);
break;
case WIN_MSG_TIMER:
{
if(msg->data.v==menu->timer_anim)
{
WIN_WindowStruct *win=(WIN_WindowStruct *)menu;
PICMENU_ItemStruct *item=&menu->item[menu->index];
WIN_SetTimerCycle (menu->timer_anim,item->img_gif.delay[item->frameNow]);
item->frameNow++; if (item->frameNow>item->img_gif.frameNumber-1) item->frameNow=0;
WIN_SetInvalidRectWhenTop(win,win->x_size/2,0,win->x_size/2,win->y_size);
}
}
break;
case WIN_MSG_KEY:
k=msg->data.p;
if (k->shortPress& KEY_VALUE_DOWN)
{
PICMENU_INDEX_ADD();
menu->move_yoff=0;
WIN_SetInvalid((WIN_WindowStruct *)menu);
}
else if (k->shortPress&KEY_VALUE_UP)
{
PICMENU_INDEX_SUB();
menu->move_yoff=0;
WIN_SetInvalid((WIN_WindowStruct *)menu);
}
break;
case WIN_MSG_MOVE:
m=msg->data.p;
switch (m->moveType)
{
case MOVE_DATA_SHORT:
if(m->x_move>((WIN_WindowStruct *)menu)->x_size/2)
{
//短按打开窗口
PICMENU_ItemStruct *item=&menu->item[menu->index];
WIN_TouchWinStruct *touch=(WIN_TouchWinStruct *)menu;
if(item->creat) item->creat(touch);
}
break;
case MOVE_DATA_TOUCHIN:
if( m->x_move<((WIN_WindowStruct *)menu)->x_size/2)
{
menu->move_start=1;
}
else
{
menu->move_start=0;
}
break;
case MOVE_DATA_MOVED:
if(menu->move_start)
{
menu->move_yoff+=m->y_move;
if (menu->move_yoff>menu->y_step/2)
{
menu->move_yoff-=menu->y_step;
PICMENU_INDEX_SUB();
}
else if (menu->move_yoff<=-menu->y_step/2)
{
menu->move_yoff+=menu->y_step;
PICMENU_INDEX_ADD();
}
}
//touch窗口的惯性滑动以x_move,y_move都为0结尾
if(m->x_move==0&&m->y_move==0)
{
menu->move_yoff=0;
}
WIN_SetInvalid ((WIN_WindowStruct *)menu);
break;
case MOVE_DATA_TOUCHOUT:
case MOVE_DATA_MOVEOUT:
menu->move_yoff=0;
WIN_SetInvalid ((WIN_WindowStruct *)menu);
break;
default:
break;
}
break;
default:
WIN_DefaultMsgLoop((WIN_WindowStruct *)menu,msg);
break;
}
}