Files
player/Project/Src/MyWinApp/mywin_user_sysfile.c
andy 045cff4cc6 整理代码
1.解决一些编译警告
2.发现png因为文件api不支持而不能使用
2025-10-18 13:58:40 +08:00

475 lines
16 KiB
C

#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;
}