#include "ff.h" #include "flash_manager.h" #include "mywin_inc.h" #include "system_file.h" // #include "nes_main.h" #include "mywin_user_photo.h" #include "mywin_user_sysfile.h" #define WIN_SYSFILE_TYPE "WIN_SysFileStruct" static const char *g_popup_itmes[] = {"打开", "重命名", "设置为背景", "复制到SD卡", "删除此项及以后的文件", "文件信息", "存储空间使用情况", "格式化"}; WIN_SysFileStruct *WIN_CreatSysFile( 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))SYSFILE_defaultMsgLoop; } WIN_SysFileStruct *ret = mymalloc(sizeof(WIN_SysFileStruct)); // 调用父类的构造函数 if (ret) { mymemset(ret, 0, sizeof(WIN_SysFileStruct)); if (0 == WIN_CreatWindowExt((WIN_WindowStruct *)ret, base, msgLoop, x, y, x_size, y_size)) { // 创建失败 myfree(ret); ret = 0; } else { // 构造 ((WIN_WindowStruct *)ret)->winType = WIN_SYSFILE_TYPE; ((WIN_WindowStruct *)ret)->bkcolor = 0x808080; ((WIN_WindowStruct *)ret)->color = 0xffffff; ret->titleHight = 30; ret->itemHight = 30; ret->itemIndent = 35; ret->itemNumOnePage = (((WIN_WindowStruct *)ret)->y_size - ret->titleHight) / ret->itemHight; ret->itemHight = (((WIN_WindowStruct *)ret)->y_size - ret->titleHight) / ret->itemNumOnePage; } } return ret; } // 清空条目 void SYSFILE_ClearItem(WIN_SysFileStruct *filder) { filder->fileNum = 0; filder->firstItemOnPage = 0; filder->index = 0; } // 添加一个文件条目 void SYSFILE_AddItem(WIN_SysFileStruct *filder, FLASH_FileStruct *file) { if (filder->fileNum < SYSFILE_FILE_MAXNUM) { mymemcpy(&filder->file[filder->fileNum], file, sizeof(FLASH_FileStruct)); filder->fileNum++; } } // 扫描文件 void SYSFILE_ScanFile(WIN_SysFileStruct *sysfile) { sysfile->fileNum = FLASH_GetFileNum(); for (int i = 0; i < sysfile->fileNum; i++) { FLASH_GetFileInfo(i, &sysfile->file[i]); } } void SYSFILE_OpenFile(WIN_SysFileStruct *sysfile) { int str_len = strlen(sysfile->file[sysfile->index].FileName); char *p_str = &sysfile->file[sysfile->index].FileName[str_len - 4]; if (strcmp(p_str, ".pic") == 0) { WIN_PicStruct pic = {0}; uint32_t file_size = 0; uint8_t *data = 0; uint8_t ret = 0; if (FLASH_FindFile(sysfile->file[sysfile->index].FileName, &file_size) != 0) { // 在外置FLASH中读取图像数据 data = mymalloc(file_size); FLASH_ReadFile(sysfile->file[sysfile->index].FileName, 0, (uint8_t *)data, file_size); ret = WIN_GetImageSize((uint8_t *)data, &pic.xsize, &pic.ysize); if (ret == 0) { pic.data = (uint16_t *)(data + 8); } PHOTO_ShowPic((WIN_WindowStruct *)sysfile, &pic); myfree(data); } } else if ((strcmp(p_str, ".nes") == 0) || (strcmp(p_str, ".NES") == 0)) { uint32_t file_size = 0; uint8_t *data = 0; uint8_t ret = 0; if (FLASH_FindFile(sysfile->file[sysfile->index].FileName, &file_size) != 0) { // 在外置FLASH中读取数据 data = mymalloc(file_size); FLASH_ReadFile(sysfile->file[sysfile->index].FileName, 0, (uint8_t *)data, file_size); WIN_KeyShieldOn(); // nes_start // (data,file_size,LCD_GetShowAddr(),LCD_GetLcdSizeX()/2-128,LCD_GetLcdSizeY()/2-120); WIN_KeyShieldOff(); myfree(data); } } else if (strcmp(p_str, ".app") == 0) { // 升级应用软件 if (MSGBOX_Inquiry((WIN_WindowStruct *)sysfile, "警告", "确定升级吗?非必要请勿操作", "确定", "取消") == 0) { // 重启到iap并且升级 指定 文件 (*(uint32_t *)0x20000000) = 0xff000002; (*(uint32_t *)0x20000004) = sysfile->index; NVIC_SystemReset(); } } else { MSGBOX_TipsTime((WIN_WindowStruct *)sysfile, "提示", "不支持的文件", "确定", 5000); } } // 消息框的绘制函数 void SYSFILE_DefaultPaint(WIN_SysFileStruct *sysfile) { // 使用双缓冲,防止闪烁 // LCD_LayerBufferOn(); int x = 0; int y = 0; int x_size = ((WIN_WindowStruct *)sysfile)->x_size; int y_size = ((WIN_WindowStruct *)sysfile)->y_size; char txt_buff[20] = {0}; WIN_PaintBackGround((WIN_WindowStruct *)sysfile); // 绘制滚动条 int scrollbar_x = x_size - 10 - 1; int scrollbar_y = y + sysfile->titleHight; int scrollbar_xsize = 10; int scrollbar_ysize = y_size - scrollbar_y; int scrollbar_tstart = sysfile->firstItemOnPage * scrollbar_ysize / sysfile->fileNum; int scrollbar_tsize = sysfile->itemNumOnePage * scrollbar_ysize / sysfile->fileNum; WIN_SetLcdColor(((WIN_WindowStruct *)sysfile)->color); WIN_DrawHLine(scrollbar_x, scrollbar_y, scrollbar_x + scrollbar_xsize - 1); WIN_DrawHLine(scrollbar_x, scrollbar_y + scrollbar_ysize - 1, scrollbar_x + scrollbar_xsize - 1); WIN_DrawVLine(scrollbar_x, scrollbar_y, scrollbar_y + scrollbar_ysize - 1); WIN_DrawVLine(scrollbar_x + scrollbar_xsize - 1, scrollbar_y, scrollbar_y + scrollbar_ysize - 1); WIN_FillRectByColor(scrollbar_x, scrollbar_y + scrollbar_tstart, scrollbar_xsize, scrollbar_tsize); // 显示标题 WIN_SetFontMode(WIN_DRAWMODE_ALONE); WIN_DrawTxtHCenterAt("系统文件管理", x_size / 2, sysfile->titleHight / 2 - WIN_GetFontHight() / 2); // 显示文件信息 sprintf(txt_buff, "%d/%d", sysfile->index + 1, sysfile->fileNum); WIN_DrawTxtAt(txt_buff, x_size - WIN_GetFontWidth() * strlen(txt_buff) / 2 - 1, sysfile->titleHight / 2 - WIN_GetFontHight() / 2); // 显示选中框 int selete_x = x; int selete_y = y + sysfile->titleHight; int selete_xsize = x_size - scrollbar_xsize - 1; int selete_ysize = sysfile->itemHight; WIN_SetLcdColor(0x00ffff); selete_y += sysfile->itemHight * (sysfile->index - sysfile->firstItemOnPage); // WIN_FillRectByColor (selete_x,selete_y,selete_xsize,selete_ysize); WIN_FillRectByColorAlpha(selete_x, selete_y, selete_xsize, selete_ysize, 16); // 显示文件 RECT_Struct rs = {0}; // 用于裁剪绘图区的矩形 rs.x = x; rs.y = y + sysfile->titleHight; rs.x_size = x_size - scrollbar_xsize - 1; rs.y_size = sysfile->itemHight; WIN_SetLcdColor(((WIN_WindowStruct *)sysfile)->color); for (int i = 0; i < sysfile->itemNumOnePage; i++) { if (i + sysfile->firstItemOnPage < sysfile->fileNum) { WIN_SetWinInvalidRect(((WIN_WindowStruct *)sysfile), &rs); // 显示图标 int img_xsize = 0; int img_ysize = 0; uint8_t *img = 0; // if (sysfile->file[i+sysfile->firstItemOnPage].type==FILDER_DIR_TYPE) //{img=filder->imgDir;} else {img=filder->imgFile;} if (img) { WIN_GetImageSize(img, &img_xsize, &img_ysize); if (img_xsize > sysfile->itemIndent) img_xsize = sysfile->itemIndent; if (img_ysize > rs.y_size) img_ysize = rs.y_size; WIN_DrawImag(x + sysfile->itemIndent / 2 - img_xsize / 2, rs.y + rs.y_size / 2 - img_ysize / 2, img_xsize, img_ysize, img); } // 显示文件名 WIN_DrawTxtAt(sysfile->file[i + sysfile->firstItemOnPage].FileName, rs.x + sysfile->itemIndent, rs.y + rs.y_size / 2 - WIN_GetFontHight() / 2); } rs.y += sysfile->itemHight; } WIN_SetWinInvalidRect(((WIN_WindowStruct *)sysfile), 0); // LCD_LayerBuffShow(); } typedef struct { char *name; } sysfile_copy_struct; // 文件复制到SD卡 static int sysfile_copy(void *ptr) { sysfile_copy_struct *t = ptr; uint32_t file_size = 0; int ret_int = 0; if (FLASH_FindFile(t->name, &file_size) != 0) { uint8_t *data = mymalloc(file_size); FLASH_ReadFile(t->name, 0, (uint8_t *)data, file_size); FIL *file = mymalloc(sizeof(FIL)); char *file_name = mymalloc(256); FRESULT ret = FR_OK; sprintf(file_name, "0:/SYS/%s", t->name); ret = f_open(file, file_name, FA_CREATE_NEW | FA_WRITE); if (ret == FR_OK) { UINT real = 0; ret = f_write(file, data, file_size, &real); if (ret != FR_OK) while (1) ; else ret_int = 1; // 返回1成功 } else ret_int = 0; f_close(file); myfree(file); myfree(file_name); myfree(data); } return ret_int; } // 删除文件 static int sysfile_del(void *ptr) { int index = (int)ptr; return FLASH_DeleteFile(index); } static void SYSFILE_Down(WIN_SysFileStruct *sysfile) { if (sysfile->index < sysfile->fileNum - 1) { sysfile->index++; if (sysfile->index >= sysfile->firstItemOnPage + sysfile->itemNumOnePage) { sysfile->firstItemOnPage++; } } else { sysfile->index = 0; sysfile->firstItemOnPage = 0; } } static void SYSFILE_Up(WIN_SysFileStruct *sysfile) { if (sysfile->index > 0) { sysfile->index--; if (sysfile->index < sysfile->firstItemOnPage) { sysfile->firstItemOnPage--; } } else { sysfile->index = sysfile->fileNum - 1; if (sysfile->fileNum > sysfile->itemNumOnePage) sysfile->firstItemOnPage = sysfile->fileNum - sysfile->itemNumOnePage; else sysfile->firstItemOnPage = 0; } } static void SYSFILE_Enter(WIN_SysFileStruct *sysfile) { int index = POPUP_SelectItem((WIN_WindowStruct *)sysfile, (char **)g_popup_itmes, 8, 100, 100); if (index == 0) { // 打开文件 SYSFILE_OpenFile(sysfile); } else if (index == 1) { // 重命名 char *txt_buff = mymalloc(256); mymemcpy(txt_buff, sysfile->file[sysfile->index].FileName, strlen(sysfile->file[sysfile->index].FileName) + 1); INPUT_KeyBoard((WIN_WindowStruct *)sysfile, txt_buff, 256); myfree(txt_buff); } else if (index == 2) { // 设置为背景 SysFile_SetBackPicPath(sysfile->file[sysfile->index].FileName); WIN_WindowStruct *home = WIN_GetWinByTitle(0, "home"); if (home) { WIN_SetBackPicPath(home, SysFile_GetSysFile()->backPicPath); MSGBOX_TipsTime((WIN_WindowStruct *)sysfile, "提示", "已设置为背景", "确定", 5000); } else { MSGBOX_TipsTime((WIN_WindowStruct *)sysfile, "提示", "设置背景失败", "确定", 5000); } } else if (index == 3) { // 复制到SD卡 sysfile_copy_struct cop = {0}; cop.name = sysfile->file[sysfile->index].FileName; if (WORKING_DoWork((WIN_WindowStruct *)sysfile, "正在复制文件到SD卡。。。", sysfile_copy, &cop)) { MSGBOX_TipsTime((WIN_WindowStruct *)sysfile, "提示", "文件复制成功", "确定", 5000); } else MSGBOX_TipsTime((WIN_WindowStruct *)sysfile, "提示", "文件复制失败", "确定", 5000); } else if (index == 4) { // 删除 if (MSGBOX_Inquiry((WIN_WindowStruct *)sysfile, "警告", "确定删除这些文件吗?", "确定", "取消") == 0) { // if (FLASH_DeleteFile(sysfile->index)==0) if (WORKING_DoWork((WIN_WindowStruct *)sysfile, "正在删除。。。", sysfile_del, (void *)sysfile->index) == 0) { MSGBOX_TipsTime((WIN_WindowStruct *)sysfile, "提示", "文件已删除", "确定", 5000); } else { MSGBOX_TipsTime((WIN_WindowStruct *)sysfile, "提示", "文件删除失败", "确定", 5000); } SYSFILE_ClearItem(sysfile); SYSFILE_ScanFile(sysfile); } } else if (index == 5) { // 文件信息 char *txt_buff = mymalloc(512); sprintf(txt_buff, "文件名:%s\n大小:%d Byte\n位置:%d", sysfile->file[sysfile->index].FileName, sysfile->file[sysfile->index].FileSize, sysfile->file[sysfile->index].Address); MSGBOX_Tips((WIN_WindowStruct *)sysfile, "文件信息", txt_buff, "确定"); myfree(txt_buff); } else if (index == 6) { // flash使用量 char *txt_buff = mymalloc(512); sprintf(txt_buff, "总空间:%d Byte\n已使用:%d Byte", FLASH_GetFlashSize(), FLASH_GetUsed()); MSGBOX_Tips((WIN_WindowStruct *)sysfile, "存储空间", txt_buff, "确定"); myfree(txt_buff); } else if (index == 7) { if (WORKING_DoWork((WIN_WindowStruct *)sysfile, "正在格式化。。。", (int (*)(void *))FLASH_EraseAllSector, 0) == 0) { MSGBOX_TipsTime((WIN_WindowStruct *)sysfile, "提示", "格式化完成", "确定", 5000); } else { MSGBOX_TipsTime((WIN_WindowStruct *)sysfile, "提示", "格式化失败", "确定", 5000); } } } // 消息框的消息处理函数 void SYSFILE_defaultMsgLoop(WIN_SysFileStruct *sysfile, WIN_MsgStruct *msg) { WIN_MoveStruct *m = 0; WIN_KeyStruct *k = 0; switch (msg->msg) { case WIN_MSG_PAINT: SYSFILE_DefaultPaint(sysfile); break; case WIN_MSG_KEY: k = msg->data.p; // 收到确定或返回键 if (k->shortPress & KEY_VALUE_DOWN) { SYSFILE_Down(sysfile); } // if (k->shortPress&KEY_VALUE_DOWN) else if (k->shortPress & KEY_VALUE_UP) { SYSFILE_Up(sysfile); } // else if (k->shortPress&KEY_VALUE_UP) else if (k->shortPress & KEY_VALUE_ENTER) { SYSFILE_Enter(sysfile); } else if (k->shortPress & KEY_VALUE_HOME) { ((WIN_WindowStruct *)sysfile)->deleteWindow((WIN_WindowStruct *)sysfile); break; // 这里直接返回, } if (k->shortPress) { WIN_SetInvalid((WIN_WindowStruct *)sysfile); } break; // case WIN_MSG_KEY: case WIN_MSG_MOVE: m = msg->data.p; switch (m->moveType) { case MOVE_DATA_SHORT: if (sysfile->touch_support == 0) { sysfile->touch_support = 1; int y_size = ((WIN_WindowStruct *)sysfile)->y_size; int x_size = ((WIN_WindowStruct *)sysfile)->x_size; sysfile->key_enter = WIN_CreatButton(((WIN_WindowStruct *)sysfile), 0, x_size - 100, y_size / 2 + 25, 90, 45); BUTTON_SetKeyString(sysfile->key_enter, "确定"); sysfile->key_back = WIN_CreatButton(((WIN_WindowStruct *)sysfile), 0, x_size - 100, y_size / 2 + 25 + 50, 90, 45); BUTTON_SetKeyString(sysfile->key_back, "返回"); sysfile->key_up = WIN_CreatButton(((WIN_WindowStruct *)sysfile), 0, x_size - 100, y_size / 2 - 50 - 50, 90, 45); BUTTON_SetKeyString(sysfile->key_up, "向上"); sysfile->key_down = WIN_CreatButton(((WIN_WindowStruct *)sysfile), 0, x_size - 100, y_size / 2 - 50, 90, 45); BUTTON_SetKeyString(sysfile->key_down, "向下"); WIN_SetInvalid((WIN_WindowStruct *)sysfile); } default: WIN_DefaultMsgLoop((WIN_WindowStruct *)sysfile, msg); break; } break; case WIN_MSG_CHID: switch (msg->data.v) { case CHID_DELETE: break; case CHID_USER: { if (msg->data2.v == BUTTON_PRESSED) { if (msg->srcWin == sysfile->key_back) { // 返回 ((WIN_WindowStruct *)sysfile) ->deleteWindow((WIN_WindowStruct *)sysfile); } else if (msg->srcWin == sysfile->key_up) { SYSFILE_Up(sysfile); } else if (msg->srcWin == sysfile->key_down) { SYSFILE_Down(sysfile); } else if (msg->srcWin == sysfile->key_enter) { SYSFILE_Enter(sysfile); } WIN_SetInvalid((WIN_WindowStruct *)sysfile); } } break; default: break; } break; default: WIN_DefaultMsgLoop((WIN_WindowStruct *)sysfile, msg); break; } } // 选则文件 int SYSFILE_ChooseFile(WIN_WindowStruct *win) { WIN_SysFileStruct *sysfile = 0; if (win) { int x, y, xsize, ysize; sysfile = WIN_CreatSysFile(win, 0, 0, 0, win->x_size, win->y_size); } else sysfile = WIN_CreatSysFile(0, 0, 0, 0, WIN_GetWinStruct()->lcd->getLcdSizeX(), WIN_GetWinStruct()->lcd->getLcdSizeY()); WIN_SetBackPicPath((WIN_WindowStruct *)sysfile, win->pic_path); SYSFILE_ScanFile(sysfile); WIN_ShowWindow((WIN_WindowStruct *)sysfile); // return WIN_RunBlock ((WIN_WindowStruct *)sysfile); return 0; }