/** * @brief 画矩形并填充. * @param x0:矩形左上角 y0:矩形左上角 x1:矩形右下角 y1:矩形右下角 color:显示的颜色. * @retval None. * @verify . */ void GUI_RectangleFill(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, TCOLOR color) { uint32_t i; /* 先找出矩形左上角与右下角的两个点,保存在(x0,y0),(x1,y1) */ if(x0>x1){ i = x0; x0 = x1; x1 = i; } if(y0>y1){ i = y0; y0 = y1; y1 = i; } /* 判断是否只是直线 */ if(y0==y1){ GUI_HLine(x0, y0, x1, color); return; } if(x0==x1) { GUI_RLine(x0, y0, y1, color); return; } while(y0<=y1){ GUI_HLine(x0, y0, x1, color); // 当前画水平线 y0++; // 下一行 } }
/**************************************************************************** * 名称:GUI_MMenuDraw() * 功能:显示主菜单,加上边框。 * 入口参数:men 主菜单句柄 * 出口参数:返回0表示操作失败,返回1表示操作成功 ****************************************************************************/ uint8 GUI_MMenuDraw(MMENU *men) { WINDOWS *mwin; uint8 i; uint8 xx; /* 参数过滤 */ if( (men->no)==0 ) return(0); mwin = men->win; // 取得窗口句柄 /* 判断是否可以显示主菜单 */ if( (mwin->hight)<50 ) return(0); if( (mwin->with)<50 ) return(0); /* 画菜单条,并显示菜主单 */ GUI_HLine(mwin->x, mwin->y + 22, mwin->x + mwin->with - 1, disp_color); xx = mwin->x; for(i=0; i<(men->no); i++) { if( (xx+MMENU_WIDTH) > (mwin->x + mwin->with) ) return(0); GUI_PutNoStr(xx+2, mwin->y + 14, men->str[i], 4); // 书写主菜单文字 xx += MMENU_WIDTH; GUI_RLine(xx, mwin->y + 12, mwin->y + 22, disp_color); // 显示主菜单分界线 } return(1); }
/**************************************************************************** * 名称:GUI_WindowsDraw() * 功能:显示窗口。根据提供的窗口参数进行画窗口。 * 入口参数:win 窗口句柄 * 出口参数:返回0表示操作失败,返回1表示操作成功 ****************************************************************************/ uint8 GUI_WindowsDraw(WINDOWS *win) { uint8 *str; int32 bak, bak1, bak2; /* 参数过滤,若窗口起出范围,则返回0 */ if( ( (win->with)<20 ) || ( (win->hight)<20 ) ) return(0); // 宽度、高度检查,限制最小窗口 if( (win->x + win->with ) > GUI_LCM_XMAX ) return(0); // 窗口宽度是否溢出 if( (win->y + win->hight ) > GUI_LCM_YMAX ) return(0); // 窗口高度是否溢出 /* 开始画窗口 */ GUI_RectangleFill(win->x, win->y, win->x + win->with - 1, win->y + win->hight - 1, back_color); GUI_Rectangle(win->x, win->y, win->x + win->with - 1, win->y + win->hight - 1, disp_color); // 画窗口 GUI_HLine(win->x, win->y + 12, win->x + win->with - 1, disp_color); // 画标题目栏 GUI_RLine(win->x + 12, win->y, win->y + 12, disp_color); // 画关闭窗号按钮 GUI_Line(win->x, win->y, win->x + 12, win->y + 12, disp_color); GUI_Line(win->x + 12, win->y, win->x, win->y + 12, disp_color); /* 写标题 */ if( win->title != NULL ) { str = win->title; bak = win->x + 15; bak1 = win->y + 3; bak2 = win->x + win->with -1; while(1) { if( (bak+8) > bak2 ) break; // 判断标题是否溢出 if(*str=='\0') break; // 判断字符串是否结束 GUI_PutChar(bak, bak1, *str++); // 显示标题 bak += 6; } } /* 写状态栏 */ if( win->state != NULL ) { if( win->hight < 60) return(0); // 判断是否可以画状态栏 /* 画状态栏 */ GUI_HLine(win->x, win->y + win->hight - 11, win->x + win->with - 1, disp_color); str = win->state; bak = win->x + 3; bak1 = win->y + win->hight - 9; bak2 = win->x + win->with -1; while(1) { if( (bak+8) > bak2 ) break; // 判断标题是否溢出 if(*str=='\0') break; // 判断字符串是否结束 GUI_PutChar(bak, bak1, *str++); // 显示标题 bak += 6; } } return(1); }
/** * @brief 画任意两点之间的直线 并可设置线宽. * @param x0:直线起点 y0: x1: y1: with: color:显示的颜色. * @retval None. * @verify . */ void GUI_LineWith(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint8_t with, TCOLOR color) { int32_t dx; // 直线x轴差值变量 int32_t dy; // 直线y轴差值变量 int8_t dx_sym; // x轴增长方向,为-1时减值方向,为1时增值方向 int8_t dy_sym; // y轴增长方向,为-1时减值方向,为1时增值方向 int32_t dx_x2; // dx*2值变量,用于加快运算速度 int32_t dy_x2; // dy*2值变量,用于加快运算速度 int32_t di; // 决策变量 int32_t wx, wy; // 线宽变量 int32_t draw_a, draw_b; /* 参数过滤 */ if(with==0) return; if(with>50) with = 50; dx = x1-x0; // 求取两点之间的差值 dy = y1-y0; wx = with/2; wy = with-wx-1; /* 判断增长方向,或是否为水平线、垂直线、点 */ if(dx>0){ // 判断x轴方向 dx_sym = 1; // dx>0,设置dx_sym=1 }else{ if(dx<0){ dx_sym = -1; // dx<0,设置dx_sym=-1 }else{ /* dx==0,画垂直线,或一点 */ wx = x0-wx; if(wx<0) wx = 0; wy = x0+wy; while(1){ x0 = wx; GUI_RLine(x0, y0, y1, color); if(wx>=wy) break; wx++; } return; } } if(dy>0){ // 判断y轴方向 dy_sym = 1; // dy>0,设置dy_sym=1 }else{ if(dy<0){ dy_sym = -1; // dy<0,设置dy_sym=-1 }else{ /* dy==0,画水平线,或一点 */ wx = y0-wx; if(wx<0) wx = 0; wy = y0+wy; while(1){ y0 = wx; GUI_HLine(x0, y0, x1, color); if(wx>=wy) break; wx++; } return; } } /* 将dx、dy取绝对值 */ dx = dx_sym * dx; dy = dy_sym * dy; /* 计算2倍的dx及dy值 */ dx_x2 = dx*2; dy_x2 = dy*2; /* 使用Bresenham法进行画直线 */ if(dx>=dy){ // 对于dx>=dy,则使用x轴为基准 di = dy_x2 - dx; while(x0!=x1){ /* x轴向增长,则宽度在y方向,即画垂直线 */ draw_a = y0-wx; if(draw_a<0) draw_a = 0; draw_b = y0+wy; GUI_RLine(x0, draw_a, draw_b, color); x0 += dx_sym; if(di<0){ di += dy_x2; // 计算出下一步的决策值 }else{ di += dy_x2 - dx_x2; y0 += dy_sym; } } draw_a = y0-wx; if(draw_a<0) draw_a = 0; draw_b = y0+wy; GUI_RLine(x0, draw_a, draw_b, color); }else{ // 对于dx<dy,则使用y轴为基准 di = dx_x2 - dy; while(y0!=y1){ /* y轴向增长,则宽度在x方向,即画水平线 */ draw_a = x0-wx; if(draw_a<0) draw_a = 0; draw_b = x0+wy; GUI_HLine(draw_a, y0, draw_b, color); y0 += dy_sym; if(di<0){ di += dx_x2; }else{ di += dx_x2 - dy_x2; x0 += dx_sym; } } draw_a = x0-wx; if(draw_a<0) draw_a = 0; draw_b = x0+wy; GUI_HLine(draw_a, y0, draw_b, color); } }
/** * @brief 画任意两点之间的直线. * @param x0:直线起点 y0: x1: y1: color:显示的颜色. * @retval None. * @verify . */ void GUI_Line(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, TCOLOR color) { int32_t dx; // 直线x轴差值变量 int32_t dy; // 直线y轴差值变量 int8_t dx_sym; // x轴增长方向,为-1时减值方向,为1时增值方向 int8_t dy_sym; // y轴增长方向,为-1时减值方向,为1时增值方向 int32_t dx_x2; // dx*2值变量,用于加快运算速度 int32_t dy_x2; // dy*2值变量,用于加快运算速度 int32_t di; // 决策变量 dx = x1-x0; // 求取两点之间的差值 dy = y1-y0; /* 判断增长方向,或是否为水平线、垂直线、点 */ if(dx>0){ // 判断x轴方向 dx_sym = 1; // dx>0,设置dx_sym=1 }else{ if(dx<0){ dx_sym = -1; // dx<0,设置dx_sym=-1 }else{ // dx==0,画垂直线,或一点 GUI_RLine(x0, y0, y1, color); return; } } if(dy>0){ // 判断y轴方向 dy_sym = 1; // dy>0,设置dy_sym=1 }else{ if(dy<0){ dy_sym = -1; // dy<0,设置dy_sym=-1 }else{ // dy==0,画水平线,或一点 GUI_HLine(x0, y0, x1, color); return; } } /* 将dx、dy取绝对值 */ dx = dx_sym * dx; dy = dy_sym * dy; /* 计算2倍的dx及dy值 */ dx_x2 = dx*2; dy_x2 = dy*2; /* 使用Bresenham法进行画直线 */ if(dx>=dy){ // 对于dx>=dy,则使用x轴为基准 di = dy_x2 - dx; while(x0!=x1){ GUI_Point(x0, y0, color); x0 += dx_sym; if(di<0){ di += dy_x2; // 计算出下一步的决策值 }else{ di += dy_x2 - dx_x2; y0 += dy_sym; } } GUI_Point(x0, y0, color); // 显示最后一点 }else{ // 对于dx<dy,则使用y轴为基准 di = dx_x2 - dy; while(y0!=y1){ GUI_Point(x0, y0, color); y0 += dy_sym; if(di<0){ di += dx_x2; }else{ di += dx_x2 - dy_x2; x0 += dx_sym; } } GUI_Point(x0, y0, color); // 显示最后一点 } }
/**************************************************************************** * 名称:GUI_SMenuDraw() * 功能:显示子菜单,加上边框。 * 入口参数:men 子菜单句柄 * 出口参数:返回0表示操作失败,返回1表示操作成功 ****************************************************************************/ uint8 GUI_SMenuDraw(SMENU *men) { WINDOWS *mwin; uint32 xx, yy; uint8 i; mwin = men->win; /* 判断是否可以显示主菜单 */ if( (mwin->hight)<50 ) return(0); if( (mwin->with)<50 ) return(0); /* 画菜子单项。下拉子菜单,以向左下拉为原则,若右边溢出则以右下拉显示 */ xx = mwin->x; xx += (men->mmenu_no)*MMENU_WIDTH; yy = mwin->y + 22; yy += (men->no) * 11 + 2; if( (xx+SMENU_WIDTH) <= (mwin->x + mwin->with - 1) ) { /* 以左下拉为原则显示子菜单 */ if( (men->mmenu_no) == 0 ) { GUI_RLine(xx+SMENU_WIDTH, mwin->y + 22, yy, disp_color); GUI_HLine(xx, yy, xx+SMENU_WIDTH, disp_color); } else { GUI_Rectangle(xx, mwin->y + 22, xx+SMENU_WIDTH, yy, disp_color); } GUI_HLine(xx+1, mwin->y + 22, xx+MMENU_WIDTH-1, back_color); } else { /* 以右下拉为原则 */ if( (xx+MMENU_WIDTH) == (mwin->x + mwin->with - 1) ) { GUI_RLine(xx-(SMENU_WIDTH-MMENU_WIDTH), mwin->y + 22, yy, disp_color); GUI_HLine(xx-(SMENU_WIDTH-MMENU_WIDTH), yy, xx+MMENU_WIDTH, disp_color); } else { GUI_Rectangle(xx-(SMENU_WIDTH-MMENU_WIDTH), mwin->y + 22, xx+MMENU_WIDTH, yy, disp_color); } GUI_HLine(xx+1, mwin->y + 22, xx+MMENU_WIDTH-1, back_color); xx = xx-(SMENU_WIDTH-MMENU_WIDTH); } /* 显示菜单文字 */ xx++; yy = mwin->y + 22 + 2; for(i=0; i<(men->no); i++) { if( i == (men->state) ) // 判断所选择的菜单项 { /* 显示背景色 */ GUI_RectangleFill(xx, yy, xx+SMENU_WIDTH-2, yy+10, disp_color); /* 显示菜单字符 */ GUI_ExchangeColor(); GUI_PutNoStr(xx+1, yy+1, men->str[i], 8); // 书写子菜单文字 GUI_ExchangeColor(); } else { /* 显示背景色 */ GUI_RectangleFill(xx, yy, xx+SMENU_WIDTH-2, yy+10, back_color); /* 显示菜单字符 */ GUI_PutNoStr(xx+1, yy+1, men->str[i], 8); // 书写子菜单文字 } yy += 11; } return(1); }