385 lines
8.7 KiB
C
385 lines
8.7 KiB
C
#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;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
|