📄 lcd2.c
字号:
/*
* Module: Lcd2.c
* Modified by: X.C.Zheng WeiHua, Kyd WeiHua, XXC Weihua
* Modified on: Date: 05-11-26 14:13
* Copyright(c) WeiHua Tech Ltd.
* Tab width: 3
* Edit Font: Courier New
*/
#include "ecrsys.h"
#include "data.h"
#include "ftype.h"
#include "lcd2.h"
#include "tft.h"
#include "font.h"
#include "tft_disp.h"
#include "stdlib.h"
#include <string.h>
#include "sysdata.h"
static BOOL Tl_TiTl_Sto_Flag = 0; /* Store the Tl_Stat flag */
static BOOL Tl_Stat_Sto_Flag = 0; /* Store the Tl_Stat flag */
static BOOL Tl_Input_Sto_Flag = 0; /* Store the Tl_Input flag */
static BOOL Tl_Sub_Sto_Flag = 0; /* Store the Tl_Sub flag*/
static byte cmd_data[255];
static BOOL Draw_Pop_Text_Flag = 0; /* The pop up text window */
BOOL Lcd_Err_Flag = 0;
static byte Lcd_Sys_Id; /* The lcd system ID */
static BOOL unconditioned_refresh_margin = 0; /* 无条件刷新边缘区域 */
static BOOL Lcd_Text_Refresh = TRUE;
static byte Refresh_Bourn = 0; /* 设置刷新的层数, 相当于多少层 */
static byte pop_type = POP_ID_NOR;
// The color variables
static byte LCD_COLOR;
static void Lcd_Text_Rewind(void);
/*
判断是否为方向键
*/
BOOL Judge_Direct_Btn(word key)
{
if ((key >= KD_DIRECT_ST) && (key <= KD_DIRECT_END) && (key != KD_PAGE_BACK_TABLE))
return TRUE;
return FALSE;
}
/*
画出方向键图形, 此处参考了徐小春显示图形的函数
*/
void Lcd_Draw_Direct_Btn(BUTTON_DEF btn, word key)
{
int x0, y0;
int x1, y1, x2, y2;
byte size;
byte posi;
byte *src_buf;
size = btn.size;
if(((size&0x0f) == 0)||((size&0xf0) == 0))
return;
posi = btn.posi;
x1 = (posi%LINE_KEY_NUM)*KEY_ITEM_WIDTH + LCD_X0dot;
y1 = (posi/LINE_KEY_NUM)*KEY_ITEM_HEIGHT;
x2 = x1 + KEY_ITEM_WIDTH*((size)&0x0f);
y2 = y1 + KEY_ITEM_HEIGHT*((size>>4)&0x0f);
Lcd_Draw_Rect_Fill(x1+2, y1+2, x2-2, y2-2, btn.fill_color);
x0 = x1 + (x2 - x1 - 24)/2;
y0 = y1 + (y2 - y1 - 16)/2;
if ( (key == KD_PAGE_LEFT_TABLE) || (key == KD_PAGE_LEFT_DEPT)
|| (key == KD_PAGE_LEFT_PLU) || (key == KD_PAGE_LEFT_CM) || (key == KD_PAGE_LEFT_WAITER) )
{
src_buf = (byte *)Font_Left;
}
else if ( (key == KD_PAGE_RIGHT_TABLE) || (key == KD_PAGE_RIGHT_DEPT)
|| (key == KD_PAGE_RIGHT_PLU) || (key == KD_PAGE_RIGHT_CM) || (key == KD_PAGE_RIGHT_WAITER) )
{
src_buf = (byte *)Font_Right;
}
else
{
return;
}
TFT_LCD_Disp_LOGO(src_buf, btn.font_color, 24, 16, x0, y0);
}
/*--------------------------------------------------------------------*
画一个按键, 包括文档区域
注意 logic_code 是0~59的按键范围
*--------------------------------------------------------------------*/
void Lcd_Draw_Btn(word logic_code, byte btn_id)
{
BUTTON_DEF Btn;
word CMD;
char tmp_str[MAX_TEXT];
byte lenth;
// Locate the button
if(btn_id == BTN_ID_TEXT)//文本框
{
Lcd_Draw_Text_Btn(TS_Btn_ID_Get(logic_code));
return;
}
else if((btn_id == BTN_ID_KEY)||(btn_id == BTN_ID_KEY_EX)||(btn_id == BTN_ID_KEY_RPT))//扩展按键
{//按键框
if (logic_code >= MAX_LAYOUT_KEY)
return;
Btn.size = TS_Key_Size_Get(&logic_code, Ts_Key_Table_Size);
Btn.posi = logic_code;
CMD = Ts_Key_Tab[logic_code];
if(btn_id == BTN_ID_KEY_EX)
{
if((CMD>= KD_DP_ST)&&(CMD <= KD_DP_END))
CMD += DeptShiftFlag*(sysflag->Dept_Shift_Inc);
else if((CMD >= KD_DPLU_ST)&&(CMD <= KD_DPLU_END))
CMD += (word)DPLUShiftFlag*(sysflag->DPLU_Shift_Inc);
}
Btn.fill_color = Get_All_Key_Color(CMD, 0);
Btn.font_color = Get_All_Key_Color(CMD, 1);
if(btn_id == BTN_ID_KEY_RPT)
{
Get_All_Key_Desc(tmp_str,MAX_TEXT, CMD);
lenth = Get_Desc_Len(tmp_str,MAX_TEXT);
Lcd_Draw_Button_Ex(Btn, tmp_str, lenth, ALIGN_MID);
}
else
{
Get_All_Key_Desc(Btn.desc,MAX_BTN_DESC_LEN+1, CMD);
if (Judge_Direct_Btn(CMD)) // 判断是否为方向键, 若是, 则调用另外一个显示函数, 目前这个函数是参考了徐小春以前所修改的显示函数
{
Lcd_Draw_Direct_Btn(Btn, CMD);
}
else
{
Lcd_Draw_Button( Btn);
}
}
return;
}
}
/*----------------------------------------------------------------------------*
* 当某个位置的按键被按下或需要弹起时, 调用此函数, 达到按键响应的动态效果
* logic_code: 按键取值的逻辑位置, 取值范围是(0~99)
* rev: 当按键被按下时, 置1, 否则为0
*----------------------------------------------------------------------------*/
void Lcd_Draw_Button_REV(word logic_code, byte rev)
{
int x1, x2, y1, y2;
word key;
byte Btn_ID;
word size;
if (logic_code >= LCD_LAYOUT_MAX_KEY)
return;
if((!Lcd_Pop_Flag)||(logic_code/VRT_KEY_NUM > LEFT_KEY_NUM)||(logic_code%VRT_KEY_NUM < LEFT_KEY_NUM))
{
key = TS_Key_Get(logic_code);
if((key == KD_NULL)||(key == KD_NULL_TS))
return;
}
if(logic_code%VRT_KEY_NUM < LEFT_KEY_NUM)
{
logic_code = (logic_code/VRT_KEY_NUM)*LEFT_KEY_NUM + (logic_code%VRT_KEY_NUM);
Btn_ID = TS_Btn_ID_Get(logic_code);
if(Btn_ID == 0xff)
return;
x1 = Func_Btn_Posi[Btn_ID][0];
x2 = Func_Btn_Posi[Btn_ID][1]-1;
y1 = Func_Btn_Posi[Btn_ID][2];
y2 = Func_Btn_Posi[Btn_ID][3]-1;
}
else //右侧按键
{
logic_code = (logic_code/VRT_KEY_NUM)*LINE_KEY_NUM +(logic_code%VRT_KEY_NUM - LEFT_KEY_NUM);
size = TS_Key_Size_Get(&logic_code, Ts_Key_Table_Size);
if(((size&0x0f) == 0)||((size>>4) == 0))
return;
x1 = (logic_code%LINE_KEY_NUM)*KEY_ITEM_WIDTH + LCD_X0dot;
y1 = (logic_code/LINE_KEY_NUM)*KEY_ITEM_HEIGHT;
x2 = x1 + KEY_ITEM_WIDTH*(size&0x0f)-1;
y2 = y1 + KEY_ITEM_HEIGHT*((size>>4)&0x0f)-1;
}
Lcd_Draw_Btn_Edge(x1, y1,x2,y2, rev);
}
/*----------------------------------------------------------------------------*
画出所有的功能按键列表, 主要用于界面全盘更新时候使用.
注意只是针对右部分的功能按键.
考虑到按键被重画的问题, 针对
当只需要画一个按键时, 请调用 Lcd_Draw_Btn() 函数
*----------------------------------------------------------------------------*/
void Lcd_Layout_Draw_Key(void)
{
byte logic_code;
byte size;
byte Btn_ID = BTN_ID_KEY;
// if((CurrMode == XREPORT)||(CurrMode == ZREPORT))
// Btn_ID = BTN_ID_KEY_RPT;
for(logic_code = 0; logic_code < MAX_LAYOUT_KEY; logic_code++)
{//只处理 size 横向倍数和纵向倍数均非0的情况.
size = Ts_Key_Table_Size[logic_code];
if(((size & 0x0f) == 0)||((size & 0xf0) == 0))
{
continue;
}
Lcd_Draw_Btn(logic_code,Btn_ID);
}
}
/*----------------------------------------------------------------------------*
函数功能:
在对应的区域显示一行字符串, 字符串的最大长度, 相对起始位置, 对齐方式
均已给出
主要是针对 BUF_ID_LCD_TEXT 和 BUF_ID_POP_TEXT 的处理
考虑的扩展主要包括 Help On Line 时的显示操作
调用的显示函数为
TFT_Lcd_Disp_Text(char *text, byte len, byte font, byte size, byte effect, byte c, int x0, int y0)
Draw the text frame text
说明: 这里在进行绘制显示区域中的文本的时候,处理模式是完全不一样的。
*----------------------------------------------------------------------------*/
void Lcd_Disp_Text_Line(byte Text_ID)
{
RECT_DEF rect;
TEXT_DEF text;
LCD_LINE_TEXT_DEF *line_text;
byte text_len;
int width;
int height;
int x1, x2, y1, y2;
int x0;
int y0;
byte i;
byte j;
byte last_dsp_line_st;
byte last_dsp_line_end;
byte refresh_all = FALSE; /* Refresh the all display flag */
byte max_lcd_text_line;
if(Text_ID == BUF_ID_LCD_TEXT)//文本文档的显示
{
if (Lcd_Text.cur_line == 0) /* 文本为空, 则不显示 */
return;
width = MAX_LCD_TEXT*Font_Size[DEFAULT_FONT][0];
height = DISP_LCD_TEXT_LINE*Font_Size[DEFAULT_FONT][1];
x1 = Func_Btn_Posi[BUF_ID_LCD_TEXT][0]+2;
x2 = Func_Btn_Posi[BUF_ID_LCD_TEXT][1]-2;
y1 = Func_Btn_Posi[BUF_ID_LCD_TEXT][2]+2;
y2 = Func_Btn_Posi[BUF_ID_LCD_TEXT][3]-2;
x0 = x1 + (x2 - x1 - width)/2;
y0 = y1 + (y2 -y1 - height)/2;
/*这里需要判断全部重画的条件, 若经过了判断仅需局部重画,则将不再画外面的矩形框*/
refresh_all = FALSE;
last_dsp_line_st = Lcd_Text.dsp_line_st;
last_dsp_line_end = Lcd_Text.dsp_line_end;
if (Lcd_Text.dsp_line_end == Lcd_Text.dsp_line_new)
{ /* No new dispaly, Indicate only refresh the all display */
refresh_all = TRUE;
}
else
{
Lcd_Text.dsp_line_end = Lcd_Text.dsp_line_new;
if (Lcd_Mode == LCD_10_INCH)
max_lcd_text_line = DISP_LCD_TEXT_LINE;
else
max_lcd_text_line = DISP_LCD_TEXT_LINE7;
if (Lcd_Text.dsp_line_end > max_lcd_text_line - 1)
Lcd_Text.dsp_line_st = Lcd_Text.dsp_line_end - (max_lcd_text_line-1);
else
Lcd_Text.dsp_line_st = 0;
if (Lcd_Text.dsp_line_st != last_dsp_line_st) /* Indicate need refresh the all dispaly */
refresh_all = TRUE;
}
if (!refresh_all)
{
j = Lcd_Text.dsp_line_new;
}
else
{//考虑不要这样整个擦除文本框, 显得速度很慢, 而且效果很不好.
if (Lcd_Text_Refresh)
Lcd_Clr_Text_Btn(BUF_ID_LCD_TEXT, 0);
j = Lcd_Text.dsp_line_st;
}
do {
line_text = &Lcd_Text.line[j];
text.text_color = line_text->text_color;
if (line_text->align == ALIGN_MID)
{
text.text = line_text->text;
text_len = line_text->len[0];
if(text_len > MAX_LCD_TEXT)
text_len = MAX_LCD_TEXT;
text.text_len = text_len;
text.x = x0 + (int)(width - Font_Size[DEFAULT_FONT][0]*text_len) / 2;
text.y = y0 + (int)(j-Lcd_Text.dsp_line_st)*Font_Size[DEFAULT_FONT][1];
if (Lcd_Text_Refresh)
Lcd_Draw_Text(&text);
}
else if (line_text->align == ALIGN_LEFT) //这种显示有些罗嗦, 可否考虑先设定好了缓冲区再显示?
{//以后考虑这里的优化
for (i = 0; i < line_text->posi_max; i++)
{
text.text = &line_text->text[line_text->posi[i] - 1];
text_len = line_text->len[i];
if ( (text_len+line_text->posi[i]-1) > MAX_LCD_TEXT)
text_len = MAX_LCD_TEXT - (line_text->posi[i]-1);
text.text_len = text_len;
text.x = x0 + (int)Font_Size[DEFAULT_FONT][0]*(line_text->posi[i]-1);
text.y = y0 + (int)Font_Size[DEFAULT_FONT][1] * (j-Lcd_Text.dsp_line_st);
if (Lcd_Text_Refresh)
Lcd_Draw_Text(&text);
}
}
j++;
}while( j <= Lcd_Text.dsp_line_end && refresh_all);
if (Lcd_Text.max_line != Lcd_Text.cur_line) /* Update the max line dispaly */
Lcd_Text.max_line = Lcd_Text.cur_line;
}
else if (Text_ID == BUF_ID_POP_TEXT)
{
if (Pop_Text.cur_line == 0) /* 文本为空, 则不显示 */
return;
width = MAX_POP_TEXT*Font_Size[DEFAULT_FONT][0];
height = DISP_POP_TEXT_LINE*Font_Size[DEFAULT_FONT][1];
x1 = Func_Btn_Posi[BUF_ID_POP_TEXT][0]+2;
x2 = Func_Btn_Posi[BUF_ID_POP_TEXT][1]-2;
y1 = Func_Btn_Posi[BUF_ID_POP_TEXT][2]+2;
y2 = Func_Btn_Posi[BUF_ID_POP_TEXT][3]-2;
x0 = x1 + (x2 - x1 - width)/2;
y0 = y1 + (y2 -y1 - height)/2;
/*这里需要判断全部重画的条件, 若经过了判断仅需局部重画,则将不再画外面的矩形框*/
refresh_all = FALSE;
last_dsp_line_st = Pop_Text.dsp_line_st;
last_dsp_line_end = Pop_Text.dsp_line_end;
if (Pop_Text.dsp_line_end == Pop_Text.dsp_line_new)
{ /* No new dispaly, Indicate only refresh the all display */
refresh_all = TRUE;
//return;
}
else
{
Pop_Text.dsp_line_end = Pop_Text.dsp_line_new;
if (Pop_Text.dsp_line_end > DISP_POP_TEXT_LINE - 1)
Pop_Text.dsp_line_st = Pop_Text.dsp_line_end - (DISP_POP_TEXT_LINE-1);
else
Pop_Text.dsp_line_st = 0;
if (Pop_Text.dsp_line_st != last_dsp_line_st) /* Indicate need refresh the all dispaly */
refresh_all = TRUE;
}
if (!refresh_all)
{
j = Pop_Text.dsp_line_new;
}
else
{
Lcd_Clr_Text_Btn(BUF_ID_POP_TEXT, 0);
j = Pop_Text.dsp_line_st;
}
do {
line_text = &Pop_Text.line[j];
text.text_color = line_text->text_color;
if (line_text->align == ALIGN_MID)
{
text.text = line_text->text;
text_len = line_text->len[0];
if (text_len > MAX_POP_TEXT)
text_len = MAX_POP_TEXT;
text.text_len = text_len;
text.x = x0 + (int)(width - Font_Size[DEFAULT_FONT][0]*text_len) / 2;
text.y = y0 + (int)Font_Size[DEFAULT_FONT][1] * (j-Pop_Text.dsp_line_st);
Lcd_Draw_Text(&text);
}
else if (line_text->align == ALIGN_LEFT)
{
for (i = 0; i < line_text->posi_max; i++)
{
text.text = &line_text->text[line_text->posi[i] - 1];
text_len = line_text->len[i];
if ( (text_len+line_text->posi[i]-1) > MAX_POP_TEXT)
text_len = MAX_POP_TEXT - (line_text->posi[i]-1);
text.text_len = text_len;
text.x = x0 + (int)Font_Size[DEFAULT_FONT][0]*(line_text->posi[i]-1);
text.y = y0 + (int)Font_Size[DEFAULT_FONT][1] * (j-Pop_Text.dsp_line_st);
Lcd_Draw_Text(&text);
}
}
}while(j++, j <= Pop_Text.dsp_line_end && refresh_all);
if (Pop_Text.max_line != Pop_Text.cur_line) /* Update the max line dispaly */
Pop_Text.max_line = Pop_Text.cur_line;
}
else
{ // 其他当行文本的处理
LCD_LINE_TEXT_DEF *tmp_text;
byte Max_line;
switch(Text_ID)
{
case BUF_ID_TL_TITLE:
tmp_text = &Tl_Title;
Tl_TiTl_Sto_Flag = 0;
break;
case BUF_ID_TL_INPUT:
tmp_text = &Tl_Input;
Tl_Input_Sto_Flag = 0;
break;
case BUF_ID_TL_SUB:
tmp_text = &Tl_Sub;
Tl_Sub_Sto_Flag = 0;
break;
default:
return;
}
Lcd_Disp_Text_btn(Text_ID, tmp_text->text, MAX_TEXT, MAX_TEXT,DEFAULT_FONT, tmp_text->align);
}
}
/* Clear the all display */
void Lcd_Draw_Cls(void)
{
byte color = DARKGRAY;
TFT_Clear(color); //color: 背景色
}
void Lcd_Draw_Cls_Ex(byte color)
{
TFT_Clear(color); //color: 背景色
}
/*---------------------------------------------------------------------------*
* 在TFT 上指定的位置开始显示一段字符串, 不能分行显示.
*---------------------------------------------------------------------------*/
void Lcd_Draw_Text(TEXT_DEF *text)
{
int x;
int y;
byte font = DEFAULT_FONT;
byte size = 0x11;
if (text->text_len == 0) /* Is zero, return */
return;
if (Draw_Pop_Text_Flag) {
x = text->x + POP_TEXT_HOR_OFFSET;
y = text->y + POP_TEXT_VRT_OFFSET;
}
else {
x = text->x;
y = text->y;
}
if (Lcd_Mode == LCD_7_INCH) { /* The 7" inch display mode */
x += X_OFFSET_7INCH;
y += Y_OFFSET_7INCH;
}
TFT_Lcd_Disp_Text(text->text, text->text_len, font, size, TRUE, text->text_color, x, y);
}
/*---------------------------------------------------------------------------*
* 在TFT 上指定的位置画一个矩形, 是实心还是空心 取决于*rect 的参数
*---------------------------------------------------------------------------*/
void Lcd_Draw_Rect(RECT_DEF *rect)
{
int x1, y1, x2, y2;
if (Draw_Pop_Text_Flag) {
x1 = rect->x1 + POP_TEXT_HOR_OFFSET;
x2 = rect->x2 + POP_TEXT_HOR_OFFSET;
y1 = rect->y1 + POP_TEXT_VRT_OFFSET;
y2 = rect->y2 + POP_TEXT_VRT_OFFSET;
}
else {
x1 = rect->x1;
x2 = rect->x2;
y1 = rect->y1;
y2 = rect->y2;
}
if (Lcd_Mode == LCD_7_INCH) { /* The 7" display mode */
x1 += X_OFFSET_7INCH;
x2 += X_OFFSET_7INCH;
y1 += Y_OFFSET_7INCH;
y2 += Y_OFFSET_7INCH;
}
if(rect->fill)
Lcd_Draw_Rect_Fill(x1, y1, x2, y2, rect->color);
else
Lcd_Draw_Rect_EMP(x1, y1, x2, y2, rect->color);
}
/*---------------------------------------------------------------------------*
* 在TFT 上指定的位置画一个圆, 是实心还是空心 取决于*rect 的参数
*---------------------------------------------------------------------------*/
void Lcd_Draw_Round(ROUND_DEF *Round)
{
if(Round->fill)
Lcd_Draw_Circle(Round->x, Round->y, Round->radius, Round->color);
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -