目录
前言
前面我们实现了显示系统框架,输入系统框架,文字系统框架,UI系统框架和页面系统框架,链接:
- 量产工具一一显示系统(一)-CSDN博客
- 量产工具一一输入系统(二)-CSDN博客
- 量产工具一一文字系统(三)-CSDN博客
- 量产工具一一UI系统(四)-CSDN博客
- 量产工具一一页面系统(五)-CSDN博客
接下来我们来实现业务系统框架,也就是把前面所实现的系统框架全部整合到一起实现功能。
一、代码流程框架
1.业务系统程序流程图
2.业务系统主页面流程图
3.main.c
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <disp_manager.h>
#include <font_manager.h>
#include <input_manager.h>
#include <page_manager.h>
int main(int argc, char **argv)
{
int error;
if (argc != 2)
{
printf("Usage: %s <font_file>\n", argv[0]);
return -1;
}
/* 初始化显示系统 */
DisplaySystemRegister();
SelectDefaultDisplay("fb");
InitDefaultDisplay();
/* 初始化输入系统 */
InputSystemRegister();
InputDeviceInit();
/* 初始化文字系统 */
FontSystemRegister();
error = SelectAndInitFont("freetype", argv[1]);
if (error)
{
printf("SelectAndInitFont err\n");
return -1;
}
/* 初始化页面系统 */
PageSystemRegister();
/* 运行业务系统的主页面 */
Page("main")->Run(NULL);
return 0;
}
4.main_page.c
在主页面流程函数下我们需要:
- 1.读取配置文件
- 2.根据配置文件生成按钮和界面
- 3.在while循环里读取输入事件
- 4.根据输入时间找到对应按钮
- 5.找到后调用出发按钮函数
static void MainPageRun(void *pParams)
{
int error;
InputEvent tInputEvent;
PButton ptButton;
PDispBuff ptDispBuff = GetDisplayBuffer();
/* 读取配置文件 */
error = ParseConfigFile();
if (error)
return ;
/* 根据配置文件生成按钮、界面 */
GenerateButtons();
while (1)
{
/* 读取输入事件 */
error = GetInputEvent(&tInputEvent);
if (error)
continue;
/* 根据输入事件找到按钮 */
ptButton = GetButtonByInputEvent(&tInputEvent);
if (!ptButton)
continue;
/* 调用按钮的OnPressed函数 */
ptButton->OnPressed(ptButton, ptDispBuff, &tInputEvent);
}
}
在下面我们再一一实现上面所用到的函数。
二、处理配置文件
对于我们要制作的页面,里面有很多按钮,那么我们怎么知道每个按钮里面都存放着什么呢?
这时我们就需要配置文件,以后我们想要打开哪个按钮,调整测试模块时,可以直接修改配置文件即可,就不需要重新修改,编译程序就可以带来非常大的灵活性。
1.配置文件示例
2.处理配置文件
创建一个ItemCfg 结构体,用于表示配置文件中的一个条目,以便于处理配置文件
3.config.h
#ifndef _CONFIG_H
#define _CONFIG_H
#include <common.h>
#define ITEMCFG_MAX_NUM 30
#define CFG_FILE "/etc/test_gui/gui.conf"
typedef struct ItemCfg {
int index;
char name[100];
int bCanBeTouched;
char command[100];
}ItemCfg, *PItemCfg;
int ParseConfigFile(void);
int GetItemCfgCount(void);
PItemCfg GetItemCfgByIndex(int index);
PItemCfg GetItemCfgByName(char *name);
#endif
4.config.c
处理配置文件主要分为下面几个步骤
- 1.打开配置文件
- 2.循环读取文件中每一行
- 3.读取每一行数据
- 4.吃掉开头的空格或者TAB
- 5.忽略注释
- 6.处理数据
#include <config.h>
#include <stdio.h>
#include <string.h>
static ItemCfg g_tItemCfgs[ITEMCFG_MAX_NUM];
static int g_iItemCfgCount = 0;
int ParseConfigFile(void)
{
FILE *fp;
char buf[100];
char *p = buf;
/* 1. 打开配置文件 */
fp = fopen(CFG_FILE, "r");
if (!fp)
{
printf("can not open cfg file %s\n", CFG_FILE);
return -1;
}
/* 循环读取文件的每一行 */
while (fgets(buf, 100, fp))
{
/* 2.1 读取每一行数据 */
buf[99] = '\0';
/* 2.2 吃掉开头的空格或TAB */
p = buf;
while (*p == ' ' || *p =='\t')
p++;
/* 2.3 忽略注释 */
if (*p == '#')
continue;
/* 2.4 处理 */
g_tItemCfgs[g_iItemCfgCount].command[0] = '\0';
g_tItemCfgs[g_iItemCfgCount].index = g_iItemCfgCount;
sscanf(p, "%s %d %s", g_tItemCfgs[g_iItemCfgCount].name, &g_tItemCfgs[g_iItemCfgCount].bCanBeTouched, \
g_tItemCfgs[g_iItemCfgCount].command);
g_iItemCfgCount++;
}
return 0;
}
/* 定义一个函数,用于获取配置文件中条目的数量 */
int GetItemCfgCount(void)
{
return g_iItemCfgCount;
}
/* 定义一个函数,用于根据索引获取配置文件中的条目 */
PItemCfg GetItemCfgByIndex(int index)
{
if (index < g_iItemCfgCount)
return &g_tItemCfgs[index];
else
return NULL;
}
/* 定义一个函数,用于根据名称获取配置文件中的条目 */
PItemCfg GetItemCfgByName(char *name)
{
int i;
for (i = 0; i < g_iItemCfgCount; i++)
{
if (strcmp(name, g_tItemCfgs[i].name) == 0)
return &g_tItemCfgs[i];
}
return NULL;
}
三、生成产品界面
想要显示如下界面,我们可以通过上面配置文件知道有哪些按钮,接下来我们需要确定每个按钮的大小和位置,需要计算出来。
1.计算每个按钮的范围
2.main_page.c
#include <config.h>
#include <stdio.h>
#include <ui.h>
#include <page_manager.h>
#include <math.h>
#include <string.h>
#define X_GAP 5
#define Y_GAP 5
static Button g_tButtons[ITEMCFG_MAX_NUM];
static void GenerateButtons(void)
{
int width, height;
int n_per_line;
int row, rows;
int col;
int n;
PDispBuff pDispBuff;
int xres, yres;
int start_x, start_y;
int pre_start_x, pre_start_y;
PButton pButton;
int i = 0;
/* 算出单个按钮的width/height */
g_tButtonCnt = n = GetItemCfgCount();
pDispBuff = GetDisplayBuffer();
xres = pDispBuff->iXres;
yres = pDispBuff->iYres;
width = sqrt(1.0/0.618 *xres * yres / n);
n_per_line = xres / width + 1;
width = xres / n_per_line;
height = 0.618 * width;
/* 居中显示: 计算每个按钮的region */
start_x = (xres - width * n_per_line) / 2;
rows = n / n_per_line;
if (rows * n_per_line < n)
rows++;
start_y = (yres - rows*height)/2;
/* 计算每个按钮的region */
for (row = 0; (row < rows) && (i < n); row++)
{
pre_start_y = start_y + row * height;
pre_start_x = start_x - width;
for (col = 0; (col < n_per_line) && (i < n); col++)
{
pButton = &g_tButtons[i];
pButton->tRegion.iLeftUpX = pre_start_x + width;
pButton->tRegion.iLeftUpY = pre_start_y;
pButton->tRegion.iWidth = width - X_GAP;
pButton->tRegion.iHeigh = height - Y_GAP;
pre_start_x = pButton->tRegion.iLeftUpX;
/* InitButton */
InitButton(pButton, GetItemCfgByIndex(i)->name, NULL, NULL, MainPageOnPressed);
i++;
}
}
/* OnDraw */
for (i = 0; i < n; i++)
g_tButtons[i].OnDraw(&g_tButtons[i], pDispBuff);
}
四、处理输入事件
我们得到的输入事件,可能来自触摸屏,也可能是其他APP发来的网络数据
对于触摸屏事件,根据iX、iY找到按钮
对于网络数据,我们限定为这样的格式:
- “name ok”、“name err”、“name 70%”
- 根据name找到按钮
对于按钮,我们要提供自己的OnPressed函数,不适用UI系统默认的函数
1.main_page.c
#include <config.h>
#include <stdio.h>
#include <ui.h>
#include <page_manager.h>
#include <math.h>
#include <string.h>
#define X_GAP 5
#define Y_GAP 5
static Button g_tButtons[ITEMCFG_MAX_NUM];
static int g_tButtonCnt;
static int MainPageOnPressed(struct Button *ptButton, PDispBuff ptDispBuff, PInputEvent ptInputEvent)
{
unsigned int dwColor = BUTTON_DEFAULT_COLOR;
char name[100];
char status[100];
char *strButton;
strButton = ptButton->name;
/* 1. 对于触摸屏事件 */
if (ptInputEvent->iType == INPUT_TYPE_TOUCH)
{
/* 1.1 分辨能否被点击 */
if (GetItemCfgByName(ptButton->name)->bCanBeTouched == 0)
return -1;
/* 1.2 修改颜色 */
ptButton->status = !ptButton->status;
if (ptButton->status)
dwColor = BUTTON_PRESSED_COLOR;
}
else if (ptInputEvent->iType == INPUT_TYPE_NET)
{
/* 2. 对于网络事件 */
/* 根据传入的字符串修改颜色 : wifi ok, wifi err, burn 70 */
sscanf(ptInputEvent->str, "%s %s", name, status);
if (strcmp(status, "ok") == 0)
dwColor = BUTTON_PRESSED_COLOR;
else if (strcmp(status, "err") == 0)
dwColor = BUTTON_DEFAULT_COLOR;
else if (status[0] >= '0' && status[0] <= '9')
{
dwColor = BUTTON_PERCENT_COLOR;
strButton = status;
}
else
return -1;
}
else
{
return -1;
}
/* 绘制底色 */
DrawRegion(&ptButton->tRegion, dwColor);
/* 居中写文字 */
DrawTextInRegionCentral(strButton, &ptButton->tRegion, BUTTON_TEXT_COLOR);
/* flush to lcd/web */
FlushDisplayRegion(&ptButton->tRegion, ptDispBuff);
return 0;
}
static void GenerateButtons(void)
{
int width, height;
int n_per_line;
int row, rows;
int col;
int n;
PDispBuff pDispBuff;
int xres, yres;
int start_x, start_y;
int pre_start_x, pre_start_y;
PButton pButton;
int i = 0;
/* 算出单个按钮的width/height */
g_tButtonCnt = n = GetItemCfgCount();
pDispBuff = GetDisplayBuffer();
xres = pDispBuff->iXres;
yres = pDispBuff->iYres;
width = sqrt(1.0/0.618 *xres * yres / n);
n_per_line = xres / width + 1;
width = xres / n_per_line;
height = 0.618 * width;
/* 居中显示: 计算每个按钮的region */
start_x = (xres - width * n_per_line) / 2;
rows = n / n_per_line;
if (rows * n_per_line < n)
rows++;
start_y = (yres - rows*height)/2;
/* 计算每个按钮的region */
for (row = 0; (row < rows) && (i < n); row++)
{
pre_start_y = start_y + row * height;
pre_start_x = start_x - width;
for (col = 0; (col < n_per_line) && (i < n); col++)
{
pButton = &g_tButtons[i];
pButton->tRegion.iLeftUpX = pre_start_x + width;
pButton->tRegion.iLeftUpY = pre_start_y;
pButton->tRegion.iWidth = width - X_GAP;
pButton->tRegion.iHeigh = height - Y_GAP;
pre_start_x = pButton->tRegion.iLeftUpX;
/* InitButton */
InitButton(pButton, GetItemCfgByIndex(i)->name, NULL, NULL, MainPageOnPressed);
i++;
}
}
/* OnDraw */
for (i = 0; i < n; i++)
g_tButtons[i].OnDraw(&g_tButtons[i], pDispBuff);
}
static int isTouchPointInRegion(int iX, int iY, PRegion ptRegion)
{
if (iX < ptRegion->iLeftUpX || iX >= ptRegion->iLeftUpX + ptRegion->iWidth)
return 0;
if (iY < ptRegion->iLeftUpY || iY >= ptRegion->iLeftUpY + ptRegion->iHeigh)
return 0;
return 1;
}
static PButton GetButtonByName(char *name)
{
int i;
for (i = 0; i < g_tButtonCnt; i++)
{
if (strcmp(name, g_tButtons[i].name) == 0)
return &g_tButtons[i];
}
return NULL;
}
static PButton GetButtonByInputEvent(PInputEvent ptInputEvent)
{
int i;
char name[100];
if (ptInputEvent->iType == INPUT_TYPE_TOUCH)
{
for (i = 0; i < g_tButtonCnt; i++)
{
if (isTouchPointInRegion(ptInputEvent->iX, ptInputEvent->iY, &g_tButtons[i].tRegion))
return &g_tButtons[i];
}
}
else if (ptInputEvent->iType == INPUT_TYPE_NET)
{
sscanf(ptInputEvent->str, "%s", name);
return GetButtonByName(name);
}
else
{
return NULL;
}
return NULL;
}
static void MainPageRun(void *pParams)
{
int error;
InputEvent tInputEvent;
PButton ptButton;
PDispBuff ptDispBuff = GetDisplayBuffer();
/* 读取配置文件 */
error = ParseConfigFile();
if (error)
return ;
/* 根据配置文件生成按钮、界面 */
GenerateButtons();
while (1)
{
/* 读取输入事件 */
error = GetInputEvent(&tInputEvent);
if (error)
continue;
/* 根据输入事件找到按钮 */
ptButton = GetButtonByInputEvent(&tInputEvent);
if (!ptButton)
continue;
/* 调用按钮的OnPressed函数 */
ptButton->OnPressed(ptButton, ptDispBuff, &tInputEvent);
}
}
static PageAction g_tMainPage = {
.name = "main",
.Run = MainPageRun,
};
void MainPageRegister(void)
{
PageRegister(&g_tMainPage);
}
五、上机测试
上电开发板,挂载 Ubuntu 的 NFS 目录,编译测试:
六、改进代码
在上面我们可以发现按钮文字大小不一,没有严格居中,太小看不清,要解决这个问题,我们可以根据配置文件的各项确定最长的名字,确定字符大小,从而让每个按钮中文字大小一样。
解决方法:
- 在 common.h 中新构造结构体描述笛卡尔取值范围。
- 在 freetype.c 文件中添加 FreetypeGetStringRegionCar 函数,在font_manager.h中进行函数声明。
- 在 disp_manager.c 文件的 DrawTextInRegionCentral 函数。
- 在 main_page.c 文件中添加 GetFontSizeForAllButton 函数,另外我们可以改进配置文件中的command,在 OnPressed 函数中,用system函数运行command。
1.common.h
#ifndef _COMMON_H
#define _COMMON_H
#ifndef NULL
#define NULL (void *)0
#endif
typedef struct Region {
int iLeftUpX;
int iLeftUpY;
int iWidth;
int iHeigh;
}Region, *PRegion;
typedef struct RegionCartesian {
int iLeftUpX;
int iLeftUpY;
int iWidth;
int iHeigh;
}RegionCartesian, *PRegionCartesian;
#endif
2.freetype.c
static int FreetypeGetStringRegionCar(char *str, PRegionCartesian ptRegionCar)
{
int i;
int error;
FT_BBox bbox;
FT_BBox glyph_bbox;
FT_Vector pen;
FT_Glyph glyph;
FT_GlyphSlot slot = g_tFace->glyph;
/* 初始化 */
bbox.xMin = bbox.yMin = 32000;
bbox.xMax = bbox.yMax = -32000;
/* 指定原点为(0, 0) */
pen.x = 0;
pen.y = 0;
/* 计算每个字符的bounding box */
/* 先translate, 再load char, 就可以得到它的外框了 */
for (i = 0; i < strlen(str); i++)
{
/* 转换:transformation */
FT_Set_Transform(g_tFace, 0, &pen);
/* 加载位图: load glyph image into the slot (erase previous one) */
error = FT_Load_Char(g_tFace, str[i], FT_LOAD_RENDER);
if (error)
{
printf("FT_Load_Char error\n");
return -1;
}
/* 取出glyph */
error = FT_Get_Glyph(g_tFace->glyph, &glyph);
if (error)
{
printf("FT_Get_Glyph error!\n");
return -1;
}
/* 从glyph得到外框: bbox */
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &glyph_bbox);
/* 更新外框 */
if ( glyph_bbox.xMin < bbox.xMin )
bbox.xMin = glyph_bbox.xMin;
if ( glyph_bbox.yMin < bbox.yMin )
bbox.yMin = glyph_bbox.yMin;
if ( glyph_bbox.xMax > bbox.xMax )
bbox.xMax = glyph_bbox.xMax;
if ( glyph_bbox.yMax > bbox.yMax )
bbox.yMax = glyph_bbox.yMax;
/* 计算下一个字符的原点: increment pen position */
pen.x += slot->advance.x;
pen.y += slot->advance.y;
}
/* return string bbox */
//*abbox = bbox;
ptRegionCar->iLeftUpX = bbox.xMin;
ptRegionCar->iLeftUpY = bbox.yMax;
ptRegionCar->iWidth = bbox.xMax - bbox.xMin + 1;
ptRegionCar->iHeigh = bbox.yMax - bbox.yMin + 1;
return 0;
}
3.disp_manager.c
void DrawTextInRegionCentral(char *name, PRegion ptRegion, unsigned int dwColor)
{
FontBitMap tFontBitMap;
RegionCartesian tRegionCar;
int iOriginX, iOriginY;
int i = 0;
int error;
/* 计算字符串的外框 */
GetStringRegionCar(name, &tRegionCar);
/* 算出第一个字符的origin */
iOriginX = ptRegion->iLeftUpX + (ptRegion->iWidth - tRegionCar.iWidth)/2 - tRegionCar.iLeftUpX;
iOriginY = ptRegion->iLeftUpY + (ptRegion->iHeigh - tRegionCar.iHeigh)/2 + tRegionCar.iLeftUpY;
/* 逐个绘制 */
while (name[i])
{
/* get bitmap */
tFontBitMap.iCurOriginX = iOriginX;
tFontBitMap.iCurOriginY = iOriginY;
error = GetFontBitMap(name[i], &tFontBitMap);
if (error)
{
printf("SelectAndInitFont err\n");
return;
}
/* draw on buffer */
DrawFontBitMap(&tFontBitMap, dwColor);
iOriginX = tFontBitMap.iNextOriginX;
iOriginY = tFontBitMap.iNextOriginY;
i++;
}
}
4.main_page.c
#include <config.h>
#include <stdio.h>
#include <ui.h>
#include <page_manager.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#define X_GAP 5
#define Y_GAP 5
static Button g_tButtons[ITEMCFG_MAX_NUM];
static int g_tButtonCnt;
static int MainPageOnPressed(struct Button *ptButton, PDispBuff ptDispBuff, PInputEvent ptInputEvent)
{
unsigned int dwColor = BUTTON_DEFAULT_COLOR;
char name[100];
char status[100];
char *strButton;
char *command_status[3] = {"err", "ok", "percent"};
int command_status_index = 0;
char command[1000];
PItemCfg ptItemCfg;
strButton = ptButton->name;
/* 1. 对于触摸屏事件 */
if ((ptInputEvent->iType == INPUT_TYPE_TOUCH) && (ptInputEvent->iPressure))
{
/* 1.1 分辨能否被点击 */
if (GetItemCfgByName(ptButton->name)->bCanBeTouched == 0)
return -1;
/* 1.2 修改颜色 */
ptButton->status = !ptButton->status;
if (ptButton->status)
{
dwColor = BUTTON_PRESSED_COLOR;
command_status_index = 1;
}
}
else if (ptInputEvent->iType == INPUT_TYPE_NET)
{
/* 2. 对于网络事件 */
/* 根据传入的字符串修改颜色 : wifi ok, wifi err, burn 70 */
sscanf(ptInputEvent->str, "%s %s", name, status);
if (strcmp(status, "ok") == 0)
{
command_status_index = 1;
dwColor = BUTTON_PRESSED_COLOR;
}
else if (strcmp(status, "err") == 0)
{
command_status_index = 0;
dwColor = BUTTON_DEFAULT_COLOR;
}
else if (status[0] >= '0' && status[0] <= '9')
{
command_status_index = 2;
dwColor = BUTTON_PERCENT_COLOR;
strButton = status;
}
else
return -1;
}
else
{
return -1;
}
/* 绘制底色 */
DrawRegion(&ptButton->tRegion, dwColor);
/* 居中写文字 */
DrawTextInRegionCentral(strButton, &ptButton->tRegion, BUTTON_TEXT_COLOR);
/* flush to lcd/web */
FlushDisplayRegion(&ptButton->tRegion, ptDispBuff);
/* 执行command */
ptItemCfg = GetItemCfgByName(ptButton->name);
if (ptItemCfg->command[0] != '\0')
{
sprintf(command, "%s %s", ptItemCfg->command, command_status[command_status_index]);
system(command);
}
return 0;
}
static int GetFontSizeForAllButton(void)
{
int i;
int max_len = -1;
int max_index = 0;
int len;
RegionCartesian tRegionCar;
float k, kx, ky;
/* 1. 找出name最长的Button */
for (i = 0; i < g_tButtonCnt; i++)
{
len = strlen(g_tButtons[i].name);
if (len > max_len)
{
max_len = len;
max_index = i;
}
}
/* 2. 以font_size =100, 算出它的外框 */
SetFontSize(100);
GetStringRegionCar(g_tButtons[max_index].name, &tRegionCar);
/* 3. 把文字的外框缩放为Button的外框 */
kx = (float)g_tButtons[max_index].tRegion.iWidth / tRegionCar.iWidth;
ky = (float)g_tButtons[max_index].tRegion.iHeigh / tRegionCar.iHeigh;
//printf("button width / str width = %d/%d = %f\n", g_tButtons[max_index].tRegion.iWidth, tRegionCar.iWidth, kx);
//printf("button height / str height = %d/%d = %f\n", g_tButtons[max_index].tRegion.iHeigh, tRegionCar.iHeigh, ky);
if (kx < ky)
k = kx;
else
k = ky;
//printf("font size = %d\n", (int)(k*100));
/* 4. 反算出font size, 只取0.80, 避免文字过于接近边界 */
return k * 100 * 0.8;
}
static void GenerateButtons(void)
{
int width, height;
int n_per_line;
int row, rows;
int col;
int n;
PDispBuff pDispBuff;
int xres, yres;
int start_x, start_y;
int pre_start_x, pre_start_y;
PButton pButton;
int i = 0;
int iFontSize;
/* 算出单个按钮的width/height */
g_tButtonCnt = n = GetItemCfgCount();
pDispBuff = GetDisplayBuffer();
xres = pDispBuff->iXres;
yres = pDispBuff->iYres;
width = sqrt(1.0/0.618 *xres * yres / n);
n_per_line = xres / width + 1;
width = xres / n_per_line;
height = 0.618 * width;
/* 居中显示: 计算每个按钮的region */
start_x = (xres - width * n_per_line) / 2;
rows = n / n_per_line;
if (rows * n_per_line < n)
rows++;
start_y = (yres - rows*height)/2;
/* 计算每个按钮的region */
for (row = 0; (row < rows) && (i < n); row++)
{
pre_start_y = start_y + row * height;
pre_start_x = start_x - width;
for (col = 0; (col < n_per_line) && (i < n); col++)
{
pButton = &g_tButtons[i];
pButton->tRegion.iLeftUpX = pre_start_x + width;
pButton->tRegion.iLeftUpY = pre_start_y;
pButton->tRegion.iWidth = width - X_GAP;
pButton->tRegion.iHeigh = height - Y_GAP;
pre_start_x = pButton->tRegion.iLeftUpX;
/* InitButton */
InitButton(pButton, GetItemCfgByIndex(i)->name, NULL, NULL, MainPageOnPressed);
i++;
}
}
iFontSize = GetFontSizeForAllButton();
//SetFontSize(iFontSize);
/* OnDraw */
for (i = 0; i < n; i++)
{
g_tButtons[i].iFontSize = iFontSize;
g_tButtons[i].OnDraw(&g_tButtons[i], pDispBuff);
}
}
static int isTouchPointInRegion(int iX, int iY, PRegion ptRegion)
{
if (iX < ptRegion->iLeftUpX || iX >= ptRegion->iLeftUpX + ptRegion->iWidth)
return 0;
if (iY < ptRegion->iLeftUpY || iY >= ptRegion->iLeftUpY + ptRegion->iHeigh)
return 0;
return 1;
}
static PButton GetButtonByName(char *name)
{
int i;
for (i = 0; i < g_tButtonCnt; i++)
{
if (strcmp(name, g_tButtons[i].name) == 0)
return &g_tButtons[i];
}
return NULL;
}
static PButton GetButtonByInputEvent(PInputEvent ptInputEvent)
{
int i;
char name[100];
if (ptInputEvent->iType == INPUT_TYPE_TOUCH)
{
for (i = 0; i < g_tButtonCnt; i++)
{
if (isTouchPointInRegion(ptInputEvent->iX, ptInputEvent->iY, &g_tButtons[i].tRegion))
return &g_tButtons[i];
}
}
else if (ptInputEvent->iType == INPUT_TYPE_NET)
{
sscanf(ptInputEvent->str, "%s", name);
return GetButtonByName(name);
}
else
{
return NULL;
}
return NULL;
}
static void MainPageRun(void *pParams)
{
int error;
InputEvent tInputEvent;
PButton ptButton;
PDispBuff ptDispBuff = GetDisplayBuffer();
/* 读取配置文件 */
error = ParseConfigFile();
if (error)
return ;
/* 根据配置文件生成按钮、界面 */
GenerateButtons();
while (1)
{
/* 读取输入事件 */
error = GetInputEvent(&tInputEvent);
if (error)
continue;
/* 根据输入事件找到按钮 */
ptButton = GetButtonByInputEvent(&tInputEvent);
if (!ptButton)
continue;
/* 调用按钮的OnPressed函数 */
ptButton->OnPressed(ptButton, ptDispBuff, &tInputEvent);
}
}
static PageAction g_tMainPage = {
.name = "main",
.Run = MainPageRun,
};
void MainPageRegister(void)
{
PageRegister(&g_tMainPage);
}
5.上机测试
上电开发板,挂载 Ubuntu 的 NFS 目录,编译测试: