📄 prog_cm.c
字号:
/*-----------------------------------------------------------------------------
* Program the Cooking Message
*---------------------------------------------------------------------------*/
#include "ecrsys.h"
#include "ftype.h"
#include "sysdata.h"
#include "data.h"
#include "keydef.h"
#include "iccard.h"
#include "mathes.h"
#include <string.h>
#include "disp.h"
#include "lcd2.h"
#include "PC_Comm.h"
#include "lcd_pop.h"
#include "program.h"
#include "stdio.h"
#if 1
static const word *Bak_Ts_Key_Tab1; /* The current key table */
static const byte *Bak_Ts_Key_Table_Size1;
word Dept_Pop_Key_Tabl[MAX_LAYOUT_KEY]; /*Popup the dept key layout on right side*/
byte Dept_Pop_Key_Tabl_Size[MAX_LAYOUT_KEY]; /*size*/
const word Dept_Pop_Key_Cmd[] = /*Command key for edit the C.M.*/
{
KD_DPSF, KD_ADD, KD_DEL, KD_ENTER, KD_CANCEL, KD_CANCEL,
};
const byte Dept_Pop_Key_Cmd_Size[] = /*Default command key size*/
{
0x11, 0x11, 0x11, 0x11, 0x12, 0x10,
};
const char Str_Cooking_message_desc[] = {"The limit description length is 24"};
const char Str_CM_Prog_Sel[][MAX_BTN_DESC_LEN+1] =
{
{"Edit"},
{"Add New"},
{"Delete"}
};
/*------------------------------------------------------------------------------
*统计总的可用CM的数量,即用户已经输入编辑的CM的数量
-----------------------------------------------------------------------------*/
WORD CM_TtlNumGet(void)
{
WORD i;
WORD cnt;
for (i = 0, cnt = 0; i < MAX_KP_SFX_NUM; i ++)
{
if (KP_Sfx_Desc[i][0] == '\0')
cnt ++;
}
return(cnt);
}
/*------------------------------------------------------------------------------
*统计某个部门已经连接的CM的数量.
*部门所能连接的CM数目<200
-----------------------------------------------------------------------------*/
BYTE CM_DeptTtlNumGet(BYTE dp_idx)
{
BYTE i;
BYTE cnt;
for (i=0,cnt = 0;i<MAX_DEPT_CM_NO; i++)
{
if (dept[dp_idx].CkMsg[i] !=0 ) /*Used record*/
cnt++;
}
return(cnt);
}
/*------------------------------------------------------------------------------
*根据指定部门号,找寻到此部门中第一个为空的CM的序号
*如果已经满(没有空的记录),则返回0xff)
*参数输入: dp_idx ---- department index
*参数输出: None:
*函数返回: 0xff -- 没有空记录
* 0 -- MAX_DEPT_CM_NO -1
*----------------------------------------------------------------------------*/
BYTE Dept_Cm_FindBlankRcrd(char dp_idx)
{
BYTE i;
for (i=0;i<MAX_DEPT_CM_NO; i++)
{
if (dept[dp_idx].CkMsg[i] ==0) /*Found one blank record*/
break;
}
if (i >= MAX_DEPT_CM_NO)
i = 0xff;
return(i);
}
/*----------------------------------------------------------------------------*
* 查找输入的cm编号开始的前一条有效的cm,查找包含对此条cm的查找
* Idx: (0 ~ MAX_KP_SFX_NUM-1)
* 返回:
* Idx: (0 ~ MAX_KP_SFX_NUM-1)
* 注意查找结束位置为0, 也即查找到编号为0 为止.
*----------------------------------------------------------------------------*/
byte CM_Srch_Pre(byte Idx)
{
byte Idx_Bak;
if(Idx >= MAX_KP_SFX_NUM)
return Idx;
Idx_Bak = (Idx + 1)%MAX_KP_SFX_NUM;
while((KP_Sfx_Desc[Idx][0] == '\0')&&(Idx != Idx_Bak))
Idx = (Idx + MAX_KP_SFX_NUM -1)%MAX_KP_SFX_NUM;
if(Idx == Idx_Bak)
Idx = MAX_KP_SFX_NUM;
return Idx;
}
/*----------------------------------------------------------------------------*
* 查找输入的cm编号开始的后一条有效的cm,查找包含对此条cm的判断
* Idx: (0 ~ MAX_KP_SFX_NUM-1)
* 返回:
* Idx: (0 ~ MAX_KP_SFX_NUM-1)
*----------------------------------------------------------------------------*/
byte Cm_Srch_Next(byte Idx)
{
byte Idx_Bak;
if(Idx >= MAX_KP_SFX_NUM)
return Idx;
Idx_Bak = (Idx + MAX_KP_SFX_NUM - 1)%MAX_KP_SFX_NUM;
while((Idx != Idx_Bak)&&(KP_Sfx_Desc[Idx][0] == '\0'))Idx++;
if(Idx == Idx_Bak)
Idx = MAX_KP_SFX_NUM;
return Idx;
}
/*----------------------------------------------------------------------------*
* 查找输入的cm编号对应当前的显示行号
* Idx: (0 ~ MAX_KP_SFX_NUM-1)
* *Cm_Disp_Tbl: 查找的table,也即当前显示的cm的序号集
* 返回:
* i: (0 ~ DISP_LCD_TEXT_LINE-1)
*----------------------------------------------------------------------------*/
byte CM_Srch_Line_Posi(byte Idx, byte *Cm_Disp_Tbl)
{
byte i;
for(i = 0; i < DISP_LCD_TEXT_LINE; i++)
{
if(Cm_Disp_Tbl[i] == Idx+1)
break;
}
return i;
}
/*-----------------------------------------------------------------------------
* Display the full Cooking Message lists
*-----------------------------------------------------------------------------
*/
void Disp_Full_CM_List(byte *Cm_Disp_Tbl, byte curr_line, byte Max_Line)
{
byte i;
Rst_Lcd_Text(); /* Reset the text*/
if(Max_Line == 0)
return;
Text_Lcd.CurrLine = curr_line;
for (i = 0; i < Max_Line; i++) // Display 8CMs information
{
memset(Text_Lcd.text[i], 0x20, MAX_TEXT);
if(Cm_Disp_Tbl[i] != 0)
xtr_strcpy(Text_Lcd.text[i], KP_Sfx_Desc[Cm_Disp_Tbl[i]-1]);
}
Lcd_Reflush_List(0);
}
/*----------------------------------------------------------------------------*
Display the cooking message
Refresh_mode --
0: 向下全屏更新 --> *Idx 是开始向下查找的起始位置
1: 向上全屏更新 --> *Idx 是开始向上查找的起始位置
2: Edit更新 --> *Idx 是刚才进行了更新的单项,此函数需要对*Idx进行步进
3: 插入 ------> *Idx 是当前插入的单项, 也是当前需要反显的单项
4: 删除 ------> *Idx 是刚才删除的单项,此函数需要对*Idx进行步进
*----------------------------------------------------------------------------*/
void CM_Prog_Disp(byte Idx, byte *Cm_Disp_Tbl, byte Refresh_mode, byte *curr_line)
{
byte i;
byte tmp_idx = 0;
byte step;
byte mode = 0xff; /*0xff-全屏刷新,0xfe-部分刷新(目前保留), 0~DISP_LCD_TEXT_LINE-1, 更新mode指定的单行*/
byte str[MAX_TEXT];
byte len;
if(Refresh_mode > 4)
return;
if(Refresh_mode == 1)/*向前查找*/
{
memset(Cm_Disp_Tbl, 0, DISP_LCD_TEXT_LINE);//清除原缓冲区的所有记录.
tmp_idx = Idx;
for(i = 0; i < DISP_LCD_TEXT_LINE; i++)
{
tmp_idx = CM_Srch_Pre(tmp_idx);
if(tmp_idx >= MAX_KP_SFX_NUM)
break;
if(tmp_idx > Idx)//查到头了
break;
Cm_Disp_Tbl[DISP_LCD_TEXT_LINE-1-i] = tmp_idx + 1;
if(tmp_idx > 0)tmp_idx--;
else {i++; break;}//注意这里的i++ 一定不可省略
}
*curr_line = i - 1;
if(i < DISP_LCD_TEXT_LINE)//如果缓冲区没有装满中途退出, 准备向后填充.
{
memmove(Cm_Disp_Tbl, &Cm_Disp_Tbl[DISP_LCD_TEXT_LINE-i], i);//移位
memset(&Cm_Disp_Tbl[i], 0, DISP_LCD_TEXT_LINE-i);
tmp_idx = Idx+1;
for(; i < DISP_LCD_TEXT_LINE; i++)//继续向后填充
{
tmp_idx = Cm_Srch_Next(tmp_idx);
if(tmp_idx >= MAX_KP_SFX_NUM)
break;
if(tmp_idx < Idx )//查到头了
break;
Cm_Disp_Tbl[i] = ++tmp_idx;
}
}
mode = 0xff;
}
else if(Refresh_mode == 2)//edit
{
if((*curr_line >= DISP_LCD_TEXT_LINE-1)||(Cm_Disp_Tbl[*curr_line+1] == 0))//修改完毕最后一行, 转到新的一页
{
Refresh_mode = 0;
}
else//页内更新
{
mode = *curr_line;
(*curr_line) ++;
}
}
else if(Refresh_mode == 3)//Add new one
{
if(KP_Sfx_Desc[Idx][0] == '\0')// 如果新增的一行不是可用行, 不予更新。
return;
for(i = 0; i < DISP_LCD_TEXT_LINE; i++)
{
if(Cm_Disp_Tbl[i] > Idx)break;
}
if((i >= DISP_LCD_TEXT_LINE)||(i == 0))
{
if(Cm_Disp_Tbl[DISP_LCD_TEXT_LINE-1] == 0)
{
for(i = DISP_LCD_TEXT_LINE; i > 0; i--)
{
if(Cm_Disp_Tbl[i-1] != 0)
break;
}
*curr_line = i;
Cm_Disp_Tbl[i] = Idx+1;
mode = 0xfe;
}
else
{
Refresh_mode = 0;//如果新加的一项不在本页内, 转到新的一页
}
}
else
{
*curr_line = i;
for(i = DISP_LCD_TEXT_LINE-1; i > *curr_line; i--)
{
Cm_Disp_Tbl[i] = Cm_Disp_Tbl[i-1];
}
Cm_Disp_Tbl[*curr_line] = Idx+1;
mode = 0xfe;
}
}
else if(Refresh_mode == 4)// delete
{
if(*curr_line < DISP_LCD_TEXT_LINE-1)
{
memmove(Cm_Disp_Tbl + *curr_line, Cm_Disp_Tbl + *curr_line +1, DISP_LCD_TEXT_LINE - *curr_line - 1);
}
tmp_idx = Cm_Srch_Next(Cm_Disp_Tbl[DISP_LCD_TEXT_LINE - 2]-1);
Cm_Disp_Tbl[DISP_LCD_TEXT_LINE - 1] = (tmp_idx >= MAX_KP_SFX_NUM)? 0 : (tmp_idx+1);
mode = 0xfe;
}
if(Refresh_mode == 0)
{
memset(Cm_Disp_Tbl, 0, DISP_LCD_TEXT_LINE);
tmp_idx = Idx;
for(i = 0; i < DISP_LCD_TEXT_LINE; i++)
{
tmp_idx = Cm_Srch_Next(tmp_idx);
if(tmp_idx >= MAX_KP_SFX_NUM)
break;
if(tmp_idx < Idx)
break;
Cm_Disp_Tbl[i] = ++tmp_idx;
}
*curr_line = 0;//
mode = 0xff;
}
Disp_Full_CM_List(Cm_Disp_Tbl, *curr_line, DISP_LCD_TEXT_LINE);
// Display the note information
Lcd_Disp_Str_Btn(BUF_ID_TL_SUB, Str_Modify_Step[0]);
}
/*
删除了一条Cooking Message以后, 部门所连接的Cooking Message也做相应的删除
*/
void CM_Prog_Dept_Ex(byte cm_idx)
{
byte i;
byte j;
cm_idx++; // 与部门的存储格式相匹配
for (i = 0; i < Max_Dept_No; i++)
{
for (j = 0; j < dept[i].cm_cnt; j++)
{
if (cm_idx == dept[i].CkMsg[j])
{
memmove(&(dept[i].CkMsg[j]), &(dept[i].CkMsg[j+1]), dept[i].cm_cnt-j-1);
dept[i].cm_cnt--;
break;
}
}
}
}
/*----------------------------------------------------------------------------*
编程cm
使用一个缓冲区CM_Curr_Disp[]保留当前页显示的cm的所有编号(1~200)
使用PAGE_UP,PAGE DOWN,UP,DOWN时,如果在页内操作,直接使用显示行号标识
如果更新页操作,直接更新缓冲区CM_Curr_Disp[]的内容。
如果进行了单行更新,直接向缓冲区更新显示内容即可。当然需要先判断是否需要显示新的页
*----------------------------------------------------------------------------*/
void CM_Prog_Main(void)
{
word key;
byte CM_Curr_Disp[DISP_LCD_TEXT_LINE];/*注意为了避免负数的计算, 此处空时为0。序号记录从1~200*/
byte CM_Idx; /*当前起始寻找的CM编号*/
byte Curr_Line; /*当前显示的行*/
byte Refresh_mode; /*0-向下更新, 1-向上更新,2-Edit后更新,
3-Add New 后更新,4-Delete 后更新,0xff-不必更新*/
Lcd_Send_Text_Buff_Str(BUF_ID_TL_TITLE, 1, Str_ParaSet_Menu[10], ALIGN_MID);
Lcd_Disp_Text_Buff(BUF_ID_TL_TITLE);
Last_Prg_Idx = IDX_NULL;
Last_Prg_Step = STEP_NULL;
CM_Idx = 0;
Refresh_mode = 0;
while(1)
{
if(GetMainMode() != CurrMode)
return;
if(Refresh_mode != 0xff)
{
CM_Prog_Disp(CM_Idx, CM_Curr_Disp, Refresh_mode, &Curr_Line);
if(Curr_Line >= DISP_LCD_TEXT_LINE)
Curr_Line = DISP_LCD_TEXT_LINE - 1;
Refresh_mode = 0xff;
}
key = GetKey();
switch(key)
{
case KD_CLEAR:
Do_Clear();
break;
case KD_PAGE_DOWN:
if(CM_Curr_Disp[DISP_LCD_TEXT_LINE-1] == 0)//如果发现当前页没有装满, 说明需要从头开始显示
CM_Idx = 0;
else //否则, 使用本页最后一个显示项的单项作为新的一页查找的起点。
CM_Idx = CM_Curr_Disp[DISP_LCD_TEXT_LINE-1]-1;
Refresh_mode = 0;
break;
case KD_PAGE_UP:
CM_Idx = CM_Curr_Disp[0]-1;//定位到当前第一条C.M.的单项准备查找
Refresh_mode = 1;
break;
case KD_DOWN:
if((Curr_Line < DISP_LCD_TEXT_LINE-1)&&(CM_Curr_Disp[Curr_Line+1] > 0))//页内变化
{
Lcd_Text_Line_Disp(Curr_Line++, FALSE);
Lcd_Text_Line_Disp(Curr_Line, TRUE);
Refresh_mode = 0xff;
}
else//跨页更新, 类同KD_PAGE_DOWN
{
if(Curr_Line >= DISP_LCD_TEXT_LINE-1)
CM_Idx = CM_Curr_Disp[DISP_LCD_TEXT_LINE-1]-1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -