Files
player/Project_App_Calendar/App_Src/win/mywin_user_picmenu.c
2025-07-05 19:47:28 +08:00

385 lines
8.5 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"
#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;
}
}