📄 gui_basic.c.svn-base
字号:
/****************************************Copyright (c)**************************************************
** 江苏高科电力自动化设备有限公司
** 开发部
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
/****************************************************************************************
* 文件名:GUI_BASIC.C
* 功能:GUI基本绘图函数。进行基本绘图运算,并调用相应的刷新程序更新LCD显示。
* 日期:2004.02.26
* 备注:图形操作层,进行各种图形运算操作。
****************************************************************************************/
#include "config.h"
#include "Value.h"
#include "math.h"
#include "Fun.h"
extern uint8 Hz12_Lib[];
extern uint8 Asc12_Lib[];
extern uint8 Hz12_All[];
/****************************************************************************
* 名称:GUI_Rectangle()
* 功能:画矩形。
* 入口参数: x0 矩形左上角的x坐标值
* y0 矩形左上角的y坐标值
* x1 矩形右下角的x坐标值
* y1 矩形右下角的y坐标值
* color 显示颜色
* 出口参数:无
* 说明:操作失败原因是指定地址超出有效范围。
****************************************************************************/
void GUI_Rectangle(uint32 x0, uint32 y0, uint32 x1, uint32 y1, TCOLOR color)
{ GUI_HLine(x0, y0, x1, color);
GUI_HLine(x0, y1, x1, color);
GUI_RLine(x0, y0, y1, color);
GUI_RLine(x1, y0, y1, color);
}
/****************************************************************************
* 名称:GUI_RectangleFill()
* 功能:填充矩形。画一个填充的矩形,填充色与边框色一样。
* 入口参数: x0 矩形左上角的x坐标值
* y0 矩形左上角的y坐标值
* x1 矩形右下角的x坐标值
* y1 矩形右下角的y坐标值
* color 填充颜色
* 出口参数:无
* 说明:操作失败原因是指定地址超出有效范围。
****************************************************************************/
void GUI_RectangleFill(uint32 x0, uint32 y0, uint32 x1, uint32 y1, TCOLOR color)
{ uint32 i;
/* 先找出矩形左上角与右下角的两个点,保存在(x0,y0),(x1,y1) */
if(x0>x1) // 若x0>x1,则x0与x1交换
{ i = x0;
x0 = x1;
x1 = i;
}
if(y0>y1) // 若y0>y1,则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_Square()
* 功能:画正方形。
* 入口参数: x0 正方形左上角的x坐标值
* y0 正方形左上角的y坐标值
* with 正方形的边长
* color 显示颜色
* 出口参数:无
* 说明:操作失败原因是指定地址超出有效范围。
****************************************************************************/
void GUI_Square(uint32 x0, uint32 y0, uint32 with, TCOLOR color)
{ if(with==0) return;
if( (x0+with) > GUI_LCM_XMAX ) return;
if( (y0+with) > GUI_LCM_YMAX ) return;
GUI_Rectangle(x0, y0, x0+with, y0+with, color);
}
/****************************************************************************
* 名称:GUI_Line()
* 功能:画任意两点之间的直线。
* 入口参数: x0 直线起点的x坐标值
* y0 直线起点的y坐标值
* x1 直线终点的x坐标值
* y1 直线终点的y坐标值
* color 显示颜色(对于黑白色LCM,为0时灭,为1时显示)
* 出口参数:无
* 说明:操作失败原因是指定地址超出有效范围。
****************************************************************************/
void GUI_Line(uint32 x0, uint32 y0, uint32 x1, uint32 y1, TCOLOR color)
{ int32 dx; // 直线x轴差值变量
int32 dy; // 直线y轴差值变量
int8 dx_sym; // x轴增长方向,为-1时减值方向,为1时增值方向
int8 dy_sym; // y轴增长方向,为-1时减值方向,为1时增值方向
int32 dx_x2; // dx*2值变量,用于加快运算速度
int32 dy_x2; // dy*2值变量,用于加快运算速度
int32 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); // 显示最后一点
}
}
/****************************************************************************
* 名称:DispStr()
*
****************************************************************************/
void DispStr(char *Str,Word x,Word y,Byte Mode)
{
Word hi;
Byte si,ic,icn;
DWord zl;
uint8 err;
OSSemPend(DispSem, 0, &err);
if(Mode==0)GUI_SetColor(WHITE, BLACK);
else GUI_SetColor(BLACK, WHITE);
for(si=0;;)
{ic=Str[si++];
if(ic==0x00||ic=='|')break;
if(ic<0xa0)
{
GUI_PutHZ(x*DISP_CHARWIDTH, y*DISP_CHARHEIGHT, (uint8 *)(Asc12_Lib+(ic-0x20)*12),6,12);
if(++x==DISP_COL)
{x=0;
if(++y==DISP_ROW)y=0;
}
}
else
{icn=Str[si++];
if(icn==0x00||ic=='|')break;
#ifdef HZ_ALL_LIB
hi=(ic-0xa1)*94+(icn-0xa1);
zl=hi*26+2;
GUI_PutHZ(x*DISP_CHARWIDTH, y*DISP_CHARHEIGHT, (uint8 *)(Hz12_All+zl),12,12);
#else
for(hi=0;;hi+=26)
{if((Hz12_Lib[hi]==ic&&Hz12_Lib[hi+1]==icn)||Hz12_Lib[hi]==0xff)
{
zl=hi+2;
GUI_PutHZ(x*DISP_CHARWIDTH, y*DISP_CHARHEIGHT, (uint8 *)(Hz12_Lib+hi+2),12,12);
break;
}
}
#endif
x+=2;
if(x>=DISP_COL)
{x=0;
if(++y==DISP_ROW)y=0;
}
}
}
OSSemPost(DispSem);
}
/****************************************************************************
* 名称:DispScreen()
*
****************************************************************************/
void DispScreen(DispDataDef *Scr)
{
if((*Scr).DispClr==1)
GUI_ClearSCR();
if((*Scr).DispMode==1)
DispMenu((MenuDataDef *)((*Scr).DispDef));
}
/****************************************************************************
* 名称:DispMenu()
*
****************************************************************************/
uint16 DispMenu(MenuDataDef *Menu)
{
uint8 tl,x,y;
uint8 Key,i;
char KeyStr[32];
if ((*Menu).TitleShow==1)
{tl=strlen((*Menu).Title);
strcpy(KeyStr,(*Menu).Title);
DispStr(KeyStr,10-(tl/2),0,0);
for(i=0;i<(*Menu).ItemNum;i++)
{x=1+(i%3)*(*Menu).StrLength;
y=i/3+1;
if(i==(*Menu).NowSelect)
DispStr(((*Menu).StrDef+i*(*Menu).StrLength),x,y,1);
else
DispStr(((*Menu).StrDef+i*(*Menu).StrLength),x,y,0);
}
}
for(;;)
{
Key=Wait_KeyPress(200);
sprintf(KeyStr, "Mpu:%03d",OSMpuBfb);
DispStr(KeyStr,0,6,0);
if (Key!=0xff)
{
sprintf(KeyStr, "Key is %02d",Key);
DispStr(KeyStr,0,7,0);
if(Key==11)return 0xff;
if(Key==12)return (*Menu).NowSelect;
if(Key==13) //Left
{if((*Menu).NowSelect==0)
(*Menu).NowSelect=(*Menu).ItemNum-1;
else
(*Menu).NowSelect--;
}
if(Key==14) //Right
{if((*Menu).NowSelect==((*Menu).ItemNum-1))
(*Menu).NowSelect=0;
else
(*Menu).NowSelect++;
}
if(Key==15) //Up
{if((*Menu).NowSelect<(*Menu).ColNum)
(*Menu).NowSelect+=(*Menu).ItemNum;
(*Menu).NowSelect-=(*Menu).ColNum;
}
if(Key==16) //Down
{(*Menu).NowSelect+=(*Menu).ColNum;
if((*Menu).NowSelect>=(*Menu).ItemNum)
(*Menu).NowSelect-=(*Menu).ItemNum;
}
if(Key<=(*Menu).ItemNum&&Key>1)
(*Menu).NowSelect=Key-2;
x=1+((*Menu).OldSelect%3)*(*Menu).StrLength;
y=(*Menu).OldSelect/3+1;
DispStr(((*Menu).StrDef+(*Menu).OldSelect*(*Menu).StrLength),x,y,0);
x=1+((*Menu).NowSelect%3)*(*Menu).StrLength;
y=(*Menu).NowSelect/3+1;
DispStr(((*Menu).StrDef+(*Menu).NowSelect*(*Menu).StrLength),x,y,1);
(*Menu).OldSelect=(*Menu).NowSelect;
}
}
}
#if GUI_LineWith_EN==1
/****************************************************************************
* 名称:GUI_LineWith()
* 功能:画任意两点之间的直线,并且可设置线的宽度。
* 入口参数: x0 直线起点的x坐标值
* y0 直线起点的y坐标值
* x1 直线终点的x坐标值
* y1 直线终点的y坐标值
* with 线宽(0-50)
* color 显示颜色
* 出口参数:无
* 说明:操作失败原因是指定地址超出有效范围。
****************************************************************************/
void GUI_LineWith(uint32 x0, uint32 y0, uint32 x1, uint32 y1, uint8 with, TCOLOR color)
{ int32 dx; // 直线x轴差值变量
int32 dy; // 直线y轴差值变量
int8 dx_sym; // x轴增长方向,为-1时减值方向,为1时增值方向
int8 dy_sym; // y轴增长方向,为-1时减值方向,为1时增值方向
int32 dx_x2; // dx*2值变量,用于加快运算速度
int32 dy_x2; // dy*2值变量,用于加快运算速度
int32 di; // 决策变量
int32 wx, wy; // 线宽变量
int32 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -