Files
player/Project/Src/MyWin/MyWinCore/mywin.c
2025-10-12 16:47:31 +08:00

747 lines
20 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"
// 定义基本窗口类型字符串
#define WIN_WINDOW_TYPE "WIN_WindowStruct"
// 窗口环境变量
static WIN_Struct g_win_struct = {0};
int WIN_Init(void) {
// 配置初始化
WIN_InitCfg();
// 屏幕初始化
WIN_GetWinStruct()->lcd->Init();
// 基础窗口初始化
WIN_GetWinStruct()->baseWin.x = 0;
WIN_GetWinStruct()->baseWin.y = 0;
WIN_GetWinStruct()->baseWin.x_size = WIN_GetWinStruct()->lcd->getLcdSizeX();
WIN_GetWinStruct()->baseWin.y_size = WIN_GetWinStruct()->lcd->getLcdSizeY();
WIN_GetWinStruct()->baseWin.baseWin = 0;
WIN_GetWinStruct()->baseWin.chidWinMaxSize = WIN_CHIDWIN_MAXNUM;
WIN_GetWinStruct()->baseWin.id = WIN_GetWinStruct()->winId++;
WIN_GetWinStruct()->baseWin.winType = WIN_WINDOW_TYPE; // 基本窗口类型
u16 color = WIN_GetWinStruct()->lcd->getLcdBkColor();
WIN_GetWinStruct()->baseWin.color = COLOR565TO888(color);
color = WIN_GetWinStruct()->lcd->getLcdBkColor();
WIN_GetWinStruct()->baseWin.bkcolor = COLOR565TO888(color);
WIN_GetWinStruct()->baseWin.msgLoop = WIN_DefaultMsgLoop;
// 主窗口的消息队列初始化
QUEUE_Init(&WIN_GetWinStruct()->baseWin.winMsgQueue, sizeof(WIN_MsgStruct),
50);
WIN_MsgStruct msg = {0};
msg.msg = WIN_MSG_INIT;
WIN_SendMsg(0, &WIN_GetWinStruct()->baseWin, &msg);
// 键盘,触摸队列初始化
QUEUE_Init(&WIN_GetWinStruct()->touchQueue, sizeof(WIN_TouchStruct), 50);
QUEUE_Init(&WIN_GetWinStruct()->keyQueue, sizeof(WIN_KeyStruct), 50);
// 显示基础窗口
WIN_ShowWindow(&WIN_GetWinStruct()->baseWin);
return 0;
}
// 返回窗口环境变量
WIN_Struct *WIN_GetWinStruct(void) { return &g_win_struct; }
// 设置窗口运行回调函数
void *WIN_SetRunCallBack(void (*callback)(void)) {
void *ret = g_win_struct.runCallBack;
if (callback)
g_win_struct.runCallBack = callback;
return ret;
}
// 获取外部数据指针,这个函数在窗口应用中调用,
// 获取之后要释放g_win_struct.ExtData 指向的内存
void *WIN_GetExtData(u32 *datasize) {
WIN_IRQ_DISABLE();
void *ret = g_win_struct.ExtData;
*datasize = g_win_struct.ExtDataSize;
g_win_struct.ExtData = 0;
g_win_struct.ExtDataSize = 0;
WIN_IRQ_ENABLE();
return ret;
}
// 放置外部数据到窗口,这个函数在其他线程或中断中调用
int WIN_PlaceExtData(void *data, u32 size) {
int ret = -1;
void *buff = mymalloc(size);
mymemcpy(buff, data, size);
WIN_IRQ_DISABLE();
if (g_win_struct.ExtData == 0) {
g_win_struct.ExtData = buff;
g_win_struct.ExtDataSize = size;
ret = 0;
} else {
ret = -1;
myfree(buff);
}
WIN_IRQ_ENABLE();
return ret;
}
// 设置在指定窗口运行的函数返回0成功
// 这个函数用于在窗口线程之外通知窗口调用函数
int WIN_RunInWindow(const char *title, void (*fun)(void *ptr), void *ptr) {
int ret = -1;
WIN_IRQ_DISABLE();
WIN_WindowStruct *win = WIN_GetWinByTitle(0, (char *)title);
if (win) {
WIN_MsgStruct msg = {0};
msg.msg = WIN_MSG_RUN;
msg.data.p = fun;
msg.data2.p = ptr;
ret = WIN_SendMsg(0, win, &msg);
}
WIN_IRQ_ENABLE();
return ret;
}
// 运行消息中的函数 ,返回0成功
// 这个函数在窗口消息循环中接收到运行消息后调用
int WIN_RunMsgFunction(WIN_MsgStruct *msg) {
int ret = -1;
if (msg->msg == WIN_MSG_RUN) {
if (msg->data.p) {
((void (*)(void *t))msg->data.p)(msg->data2.p);
ret = 0;
}
}
return ret;
}
// 在堆中创建一个窗口,返回窗口的指针
WIN_WindowStruct *WIN_CreatWindow(WIN_WindowStruct *base,
void (*msgLoop)(struct _WIN_WindowStruct *win,
WIN_MsgStruct *msg),
int x, int y, int x_size, int y_size) {
if (base == 0)
base = WIN_GetBaseWindow(); // 没有父窗口,默认父窗口
WIN_WindowStruct *ret = mymalloc(sizeof(WIN_WindowStruct));
mymemset(ret, 0, sizeof(WIN_WindowStruct));
u16 color = WIN_GetWinStruct()->lcd->getLcdBkColor();
ret->bkcolor = COLOR565TO888(color);
color = WIN_GetWinStruct()->lcd->getLcdColor();
ret->color = COLOR565TO888(color);
ret->chidWinMaxSize = WIN_CHIDWIN_MAXNUM;
ret->x = x;
ret->y = y;
ret->x_size = x_size;
ret->y_size = y_size;
ret->id = WIN_GetWinStruct()->winId++; // 设置窗口唯一ID
ret->winType = WIN_WINDOW_TYPE; // 基本窗口类型
ret->baseWin = base; // 注册父窗口
if (msgLoop)
ret->msgLoop = msgLoop; // 设置消息处理函数
else
ret->msgLoop = WIN_DefaultMsgLoop; // 设置默认消息处理函数
ret->deleteWindow = WIN_DeleteWindow; // 设置销毁函数
if (WIN_AddToChidList(base, ret) == 0) {
QUEUE_Init(&ret->winMsgQueue, sizeof(WIN_MsgStruct), 50);
WIN_MsgStruct msg = {0};
msg.msg = WIN_MSG_INIT;
WIN_SendMsg(0, ret, &msg);
return ret;
} else {
myfree(ret);
return 0;
}
}
// 创建已经实例化的窗口,返回1创建成功
int WIN_CreatWindowExt(WIN_WindowStruct *win, WIN_WindowStruct *base,
void (*msgLoop)(struct _WIN_WindowStruct *win,
WIN_MsgStruct *msg),
int x, int y, int x_size, int y_size) {
if (base == 0)
base = WIN_GetBaseWindow(); // 没有父窗口,默认父窗口
mymemset(win, 0, sizeof(WIN_WindowStruct));
u16 color = WIN_GetWinStruct()->lcd->getLcdBkColor();
win->bkcolor = COLOR565TO888(color);
color = WIN_GetWinStruct()->lcd->getLcdColor();
win->color = COLOR565TO888(color);
win->chidWinMaxSize = WIN_CHIDWIN_MAXNUM;
win->x = x;
win->y = y;
win->x_size = x_size;
win->y_size = y_size;
win->id = WIN_GetWinStruct()->winId++; // 设置窗口唯一ID
win->winType = WIN_WINDOW_TYPE; // 基本窗口类型
win->baseWin = base; // 注册父窗口
if (msgLoop)
win->msgLoop = msgLoop; // 设置消息处理函数
else
win->msgLoop = WIN_DefaultMsgLoop; // 设置默认消息处理函数
win->deleteWindow = WIN_DeleteWindow; // 设置销毁函数
if (WIN_AddToChidList(base, win) == 0) {
QUEUE_Init(&win->winMsgQueue, sizeof(WIN_MsgStruct), 50);
WIN_MsgStruct msg = {0};
msg.msg = WIN_MSG_INIT;
WIN_SendMsg(0, win, &msg);
return 1;
} else {
return 0;
}
}
// 销毁一个窗口,资源回收
void WIN_DeleteWindow(WIN_WindowStruct *win) {
// 调用子窗口的销毁函数
while (win->chidWinNum) {
(win->chid)->deleteWindow(win->chid);
}
// 在父窗口的窗口列表中删除
WIN_DelFromChidList(win->baseWin, win);
WIN_MsgStruct msg = {0};
// 告知父窗口,子窗口已删除
msg.msg = WIN_MSG_CHID;
msg.data.v = CHID_DELETE;
msg.data2.v = win->id;
WIN_SendMsg(win, win->baseWin, &msg);
// 清空消息队列
WIN_ClearMsgQueue(win);
// 发送delete消息
msg.msg = WIN_MSG_DELETE;
WIN_SendMsg(0, win, &msg);
// 通过运行一遍消息循环让窗口处理善后工作
WIN_Working(win);
// 父窗口需要重绘
WIN_SetInvalidRect(win->baseWin, win->x, win->y, win->x_size, win->y_size);
// 删除创建的定时器
WIN_WinDeleteTimer(win);
// 取消置顶
WIN_ResetAsTopWin(win);
// 销毁队列
QUEUE_Delete(&win->winMsgQueue);
// 当前在阻塞运行本窗口,返回
if (g_win_struct.BlockWin[0] == win) {
WIN_SetBlockWinReturn(-1, 0, 0);
}
// 清除窗口无效标志
if (win->invald) {
win->invald = 0;
g_win_struct.numOfWindowToPrint--;
}
// printf ("deleteWin:%s\r\n",win->winType);
// 删除窗口,如果当前还在窗口的消息循环里,则不能立即释放内存
if (win->msgLoopEnter) {
win->memFree = myfree;
} else {
myfree(win);
}
}
// 将指定窗口设置为置顶,返回1添加成功
int WIN_SetAsTopWin(WIN_WindowStruct *win) {
int i = 0;
// for (i=0;g_win_struct.TopWin[i];i++);
i = g_win_struct.TopWinNum;
if (i < WIN_TOP_MAXNUM) {
g_win_struct.TopWin[i] = win;
g_win_struct.TopWinNum++;
return 1;
} else {
return 0;
}
}
// 窗口取消置顶返回1成功
int WIN_ResetAsTopWin(WIN_WindowStruct *win) {
int i = 0;
for (i = 0; i < g_win_struct.TopWinNum; i++) {
if (g_win_struct.TopWin[i] == win) {
g_win_struct.TopWin[i] = 0;
// 后面的窗口向前移
g_win_struct.TopWinNum--;
for (; i < g_win_struct.TopWinNum; i++) {
g_win_struct.TopWin[i] = g_win_struct.TopWin[i + 1];
}
return 1;
}
}
return 0;
}
// 根据指定id号获取窗口指针
WIN_WindowStruct *WIN_GetWindowStructById(WIN_WindowStruct *win, u32 id) {
WIN_WindowStruct *ret = 0;
if (win == 0)
win = WIN_GetBaseWindow();
if (win->id == id) {
return win;
} else {
WIN_WindowStruct *prev = WIN_GetLastChidWin(win);
for (int i = win->chidWinNum; i > 0; i--) {
if (ret = WIN_GetWindowStructById(prev, id), ret) {
return ret;
}
prev = prev->prev;
}
}
return ret;
}
// 从子窗口列表中删除指定窗口
int WIN_DelFromChidList(WIN_WindowStruct *win, WIN_WindowStruct *chidWin) {
WIN_WindowStruct *next = win->chid;
for (int i = 0; i < win->chidWinNum; i++) {
if (next == chidWin) {
if(next != win->chid) {
next->prev->next = next->next;
} else {
win->chid = next->next;
}
if(next->next){
next->next->prev = next->prev;
}else{
win->chid->prev = next->prev;
}
win->chidWinNum--; // 子窗口个数减一
return 0;
}
next = next->next;
}
return -1;
}
// 把指定子窗口设置为最高
int WIN_SetChidWinTop(WIN_WindowStruct *win, WIN_WindowStruct *chidWin) {
WIN_WindowStruct *t = 0;
WIN_WindowStruct *next = win->chid;
for (int i = 0; i < win->chidWinNum; i++) {
if (next == chidWin) {
t = next;
if(next != win->chid) {
next->prev->next = next->next;
} else {
win->chid = next->next;
}
if(next->next){
next->next->prev = next->prev;
}else{
win->chid->prev = next->prev;
}
t->next = 0;
t->prev = win->chid->prev;
win->chid->prev->next = t;
win->chid->prev = t;
return 0;
}
next = next->next;
}
return -1;
}
// 添加窗口到子窗口列表中
int WIN_AddToChidList(WIN_WindowStruct *win, WIN_WindowStruct *chidWin) {
if (win->chidWinNum < win->chidWinMaxSize) {
chidWin->next = 0;
if(win->chid == 0){
win->chid = chidWin;
}else{
chidWin->prev = win->chid->prev;
win->chid->prev->next = chidWin;
}
win->chid->prev = chidWin;
win->chidWinNum++;
return 0;
} else {
return -1;
}
}
// 判断目标窗口是不是子窗口是返回1
int WIN_CheckChidWin(WIN_WindowStruct *win, WIN_WindowStruct *chid) {
WIN_WindowStruct *next = win->chid;
for (int i = 0; i < win->chidWinNum; i++) {
if (next == chid)
return 1;
next = next->next;
}
return 0;
}
// 找到指定窗口在屏幕上的坐标和大小
void WIN_GetWinPosOnLcd(WIN_WindowStruct *win, int *x, int *y, int *x_size,
int *y_size) {
*x = 0;
*y = 0;
*x_size = win->x_size;
*y_size = win->y_size;
// 遍历父窗口获得窗口的实际屏幕坐标
WIN_WindowStruct *t = win;
do {
*x += t->x;
*y += t->y;
t = t->baseWin;
} while (t);
}
// 阻塞窗口运行结束时设置返回值
void WIN_SetBlockWinReturn(int ret, void *data, int datasize) {
g_win_struct.BlockWinReturn = ret;
// 上个阻塞窗口的数据没有读取,这里丢弃掉
if (g_win_struct.BlockWinData)
myfree(g_win_struct.BlockWinData);
if (data && datasize) {
g_win_struct.BlockWinData = mymalloc(datasize);
mymemcpy(g_win_struct.BlockWinData, data, datasize);
g_win_struct.BlockWinDataSize = datasize;
} else {
g_win_struct.BlockWinData = 0;
g_win_struct.BlockWinDataSize = 0;
}
// 调用了这个函数之后窗口返回
// 这里执行窗口栈出栈
if (g_win_struct.BlockWinNum) {
g_win_struct.BlockWinNum--;
for (int i = 0; i < g_win_struct.BlockWinNum; i++) {
g_win_struct.BlockWin[i] = g_win_struct.BlockWin[i + 1];
}
g_win_struct.BlockWin[g_win_struct.BlockWinNum] = 0;
}
}
// 获取阻塞窗口的数据
int WIN_GetBlockWinReturn(int *ret, void *buff, int buffsize) {
int size = buffsize;
if (size > g_win_struct.BlockWinDataSize)
size = g_win_struct.BlockWinDataSize;
*ret = g_win_struct.BlockWinReturn;
if (g_win_struct.BlockWinData) {
mymemcpy(buff, g_win_struct.BlockWinData, size);
myfree(g_win_struct.BlockWinData);
// 解决free(g_win_struct.BlockWinData)之后在函数WIN_SetBlockWinReturn再次free的bug
// 2020.8.3
g_win_struct.BlockWinData = 0;
}
return size;
}
// 返回基础窗口指针
WIN_WindowStruct *WIN_GetBaseWindow(void) {
return &WIN_GetWinStruct()->baseWin;
}
// 返回最后一次运行的窗口
WIN_WindowStruct *WIN_GetCurrentWindow(void) {
return WIN_GetWinStruct()->winCurrent;
}
// 找到顶端可控窗口
WIN_WindowStruct *WIN_FindTopWin(WIN_WindowStruct *win) {
WIN_WindowStruct *ret = 0;
WIN_WindowStruct *prev = WIN_GetLastChidWin(win);
if (win && (win->chidWinNum)) {
for (int i = win->chidWinNum; i > 0; i--) {
ret = WIN_FindTopWin(prev);
if (ret)
return ret;
prev = prev->prev;
}
}
// 本窗口接受消息处理并且不是子窗口
if (win && (win->keyShield == 0) && (win->keyChid == 0))
return win;
else
return 0;
}
// 查找win是否被遮挡返回1
int WIN_FindBlock(WIN_WindowStruct *win) {
RECT_Struct r1 = {0};
RECT_Struct r2 = {0};
WIN_WindowStruct *top = 0;
WIN_WindowStruct *base = win->baseWin;
WIN_WindowStruct *next = win->chid;
WIN_WindowStruct *prev;
// 该窗口被遮挡只可能是其子窗口和其同辈父辈窗口
for (int i = 0; i < win->chidWinNum; i++) {
top = next;
if ((top->keyShield == 1) || (top->keyChid == 1))
continue;
r1.x = 0;
r1.y = 0;
r1.x_size = win->x_size;
r1.y_size = win->y_size;
r2.x = top->x;
r2.y = top->y;
r2.x_size = top->x_size;
r2.y_size = top->y_size;
if (POS_RectIntersection(&r1, &r1, &r2)) {
return 1;
}
next = next->next;
}
while (base) {
prev = WIN_GetLastChidWin(base);
for (int i = base->chidWinNum; i > 0; i--) {
top = prev;
if (top == win) {
// 只比较在此窗口之前的窗口
// 若没有被遮挡,则继续判断其父窗口是否被遮挡
win = base;
break;
}
WIN_GetWinPosOnLcd(top, &r1.x, &r1.y, &r1.x_size, &r1.y_size);
WIN_GetWinPosOnLcd(win, &r2.x, &r2.y, &r2.x_size, &r2.y_size);
if (POS_RectIntersection(&r1, &r1, &r2)) {
return 1;
}
prev = prev->prev;
}
base = base->baseWin;
}
return 0;
}
// 屏蔽和接触屏蔽子窗口的按键和键盘消息
int WIN_SetChildWinkeyShield(WIN_WindowStruct *win, int power) {
WIN_WindowStruct *prev = WIN_GetLastChidWin(win);
for (int i = win->chidWinNum - 1; i >= 0; i--) {
prev->keyShield = power;
prev = prev->prev;
}
return 1;
}
// 通过指定的坐标找到顶端可控的窗口,没找到返回0
WIN_WindowStruct *WIN_FindTopWinByPos(WIN_WindowStruct *win, int x, int y) {
WIN_WindowStruct *ret = win;
int win_x_s = 0;
int win_y_s = 0;
int x_size = win->x_size;
int y_size = win->y_size;
WIN_WindowStruct *prev = WIN_GetLastChidWin(win);
WIN_GetWinPosOnLcd(win, &win_x_s, &win_y_s, &x_size, &y_size);
WIN_WindowStruct *t = 0;
if (((x >= win_x_s) && (x < win_x_s + x_size)) &&
((y >= win_y_s) && (y < win_y_s + y_size)) && (win->keyShield == 0)) {
// 在本窗口内,查找是否有子窗口
// 从最后开始查找,因为越最后的显示在越前面
for (int i = win->chidWinNum - 1; i >= 0; i--) {
t = WIN_FindTopWinByPos(prev, x, y);
if (t) {
ret = t; // 找到了最前面的窗口
break;
}
prev = prev->prev;
}
} else {
// 指定点不在本窗口之类
ret = 0;
}
return ret;
}
// 返回两个窗口的共同父窗口没有共同父窗口返回0
WIN_WindowStruct *WIN_FindPrent(WIN_WindowStruct *win1,
WIN_WindowStruct *win2) {
while ((win1) && (win2)) {
if (win1 == win2)
return win1;
win1 = win1->baseWin;
win2 = win2->baseWin;
}
return 0;
}
// 设置窗口标题
void WIN_SetWinTitle(WIN_WindowStruct *win, char *title) {
int len = strlen(title);
if (len > WIN_WINTITLE_MAXLEN - 1) {
len = WIN_WINTITLE_MAXLEN - 1;
}
mymemcpy(win->winTitle, title, len);
win->winTitle[len] = 0;
}
// 根据窗口标题找到窗口指针
// 深度优先搜索
WIN_WindowStruct *WIN_GetWinByTitle(WIN_WindowStruct *win, char *title) {
WIN_WindowStruct *ret = 0;
if (win == 0)
win = WIN_GetBaseWindow();
WIN_WindowStruct *next = win->chid;
if (strcmp(win->winTitle, title) == 0) {
ret = win;
} else {
for (int i = 0; i < win->chidWinNum; i++) {
if (ret = WIN_GetWinByTitle(next, title), ret)
break;
next = next->next;
}
}
return ret;
}
// 根据窗口坐标设置LCD的活动窗口,所有绘制操作都在这个窗口之内
void WIN_EnterPaint(WIN_WindowStruct *win) {
int x = 0;
int y = 0;
int x_size = win->x_size;
int y_size = win->y_size;
WIN_GetWinPosOnLcd(win, &x, &y, &x_size, &y_size);
WIN_GetWinStruct()->lcd->setWindow(x, y, x_size, y_size);
}
// 设置无效区矩形,此矩形会被限制在窗口无效区之内
void WIN_SetWinInvalidRect(WIN_WindowStruct *win, RECT_Struct *r) {
if (r == 0)
r = &win->invaldRect;
RECT_Struct out = {0};
POS_RectIntersection(&out, r, &win->invaldRect);
int x = out.x;
int y = out.y;
int x_size = out.x_size;
int y_size = out.y_size;
g_win_struct.Invalid_x = x;
g_win_struct.Invalid_y = y;
g_win_struct.Invalid_x_size = x_size;
g_win_struct.Invalid_y_size = y_size;
}
// 获取窗口无效区矩形
void WIN_GetWinInvalidRect(WIN_WindowStruct *win, RECT_Struct *r) {
r->x = g_win_struct.Invalid_x;
r->y = g_win_struct.Invalid_y;
r->x_size = g_win_struct.Invalid_x_size;
r->y_size = g_win_struct.Invalid_y_size;
}
// 在窗口绘制时,判断需不需要绘制顶端窗口
void WIN_TopWinPaint(WIN_WindowStruct *win) {
RECT_Struct r1 = {0};
RECT_Struct r2 = {0};
RECT_Struct rout = {0};
WIN_GetWinPosOnLcd(win, &r1.x, &r1.y, &r1.x_size, &r1.y_size);
for (int i = 0; i < g_win_struct.TopWinNum; i++) {
WIN_GetWinPosOnLcd(g_win_struct.TopWin[i], &r2.x, &r2.y, &r2.x_size,
&r2.y_size);
if (POS_RectIntersection(&rout, &r1, &r2) == 1) {
// 需要刷新顶端窗口
WIN_SetInvalidRect(g_win_struct.TopWin[i], rout.x - r2.x, rout.y - r2.y,
rout.x_size, rout.y_size);
}
}
}
// 窗口默认的绘制函数
void WIN_DefaultPaint(WIN_WindowStruct *win) {
WIN_PaintBackGround(win);
// WIN_SetLcdColor (win->color);
// WIN_Clear();
// WIN_DrawHLine(0,0,LCD_GetWindowSizeX()-1);
// WIN_DrawVLine(0,0,LCD_GetWindowSizeY()-1);
// WIN_DrawHLine(0,LCD_GetWindowSizeY()-1,LCD_GetWindowSizeX()-1);
// WIN_DrawVLine(LCD_GetWindowSizeX()-1,0,LCD_GetWindowSizeY()-1);
}
// 显示窗口
void WIN_ShowWindow(WIN_WindowStruct *win) {
// 把窗口设置为无效,
WIN_SetInvalid(win);
// 通过运行一遍消息循环来显示
// WIN_Working (win);
}
// 绘制背景
void WIN_PaintBackGround(WIN_WindowStruct *win) {
// 如果有图片就显示图片
WIN_SetLcdBkColor(win->bkcolor);
WIN_PicStruct *pic = 0;
if (win->drawBackPic) {
win->drawBackPic();
} else if (pic = WIN_GetPicNoAlpha(win->pic_path), pic) {
WIN_DrawPic(pic, 0, 0, ((WIN_WindowStruct *)win)->x_size,
((WIN_WindowStruct *)win)->y_size);
} else if (WIN_DrawPic(&win->pic, 0, 0, ((WIN_WindowStruct *)win)->x_size,
((WIN_WindowStruct *)win)->y_size)) {
} else {
WIN_Clear();
}
}
void WIN_SetColor(WIN_WindowStruct *win, u32 color) { win->color = color; }
void WIN_SetBkColor(WIN_WindowStruct *win, u32 bkcolor) {
win->bkcolor = bkcolor;
}
// 设置页面的背景图片路径
void WIN_SetBackPicPath(WIN_WindowStruct *win, char *path) {
if (path) {
int len = strlen(path);
if (len + 1 > WIN_FILE_PATH_MAXLEN)
printf("%s:err,pic path too long\r\n", __func__);
mymemcpy(&win->pic_path, path, len + 1);
WIN_PicStruct *pic = WIN_GetPic(win->pic_path);
if (pic)
mymemcpy(&win->pic, pic, sizeof(WIN_PicStruct));
} else {
int len = strlen(path);
mymemset(&win->pic_path, 0, len + 1);
}
}
// 设置页面的背景图片
void WIN_SetBackPic(WIN_WindowStruct *win) {
WIN_PicStruct pic = {0};
WIN_WindowStruct *base = win->baseWin;
WIN_PicStruct *pic_base = WIN_GetPic(base->pic_path);
if (pic_base) {
int x = win->x;
int y = win->y;
if ((y < pic_base->ysize) && (x < pic_base->xsize)) {
pic.data = pic_base->data + pic_base->xsize * y + x;
pic.xsize = pic_base->xsize;
pic.ysize = pic_base->ysize - y - 1;
}
mymemcpy(&win->pic, &pic, sizeof(WIN_PicStruct));
} else {
mymemset(&win->pic, 0, sizeof(WIN_PicStruct));
}
}
// 设置页面的画背景函数
void *WIN_SetBackFun(WIN_WindowStruct *win, void (*fun)(void)) {
void *ret = win->drawBackPic;
if (fun) {
win->drawBackPic = fun;
}
return ret;
}