【电子量产工具】6. 业务系统
文章目录
- 前言
- 一、业务系统分析
- 二、处理配置文件
- 三、生成界面
- 四、根据输入事件找到按钮
- 五、业务系统总流程测试
- 测试效果:
- 总结
前言
最近看了 电子量产工具 这个项目,本专栏是对该项目的一个总结。
一、业务系统分析
前面实现了各个子系统:显示、输入、文字、UI、页面,它们只是提供基础能力,跟业务逻辑没有关系。这样的架构很容易扩展,可以在这上面实现各种业务,对于不同的产品,我们只需要写出自己页面函数。
那么对于我们的带电子量产工具,是怎么设置 的主页面呢?
首先 观赏 最终实验效果:
可以看到在这个主界面上有很多按键,按键上有各自的名字。初始时,按键是红色,当点击按键时,变成绿色。只有一些按键可以通过点击改变颜色,有的可以通过网络输入改变颜色,甚至可以显示进度蓝色。
可以创建一个配置文件 来描述各个按键的特点:
我们编写 主页面代码时,需要先从配置文件中解析 出数据,再根据数据生成按钮。
当有事件发生时,就可以找到对应按钮,再 根据配置文案金的数据 执行相应的 点击函数。
二、处理配置文件
- 对于配置文件的每一行,都创建一个ItemCfg 结构体。(每一个按钮)
typedef struct ItemCfg {int index;char name[100];int bCanBeTouched; // 是否可以被点击char command[100]; // 状态发生变化时 调用的命令
}ItemCfg, *PItemCfg;
- 解析配置文件。
int ParseConfigFile(void)
{FILE *fp;char buf[100];char *p = buf;/* 1. open config file */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 read each line */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];elsereturn 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;
}
三、生成界面
- 之前 在 页面系统 中写的是 默认的按下函数。
对于按钮,我们要提供自己的OnPressed函数,不适用UI系统默认的函数,这里编写 main_page 按下函数。
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; }elsereturn -1;}else{return -1;}/* 绘制底色 */DrawRegion(&ptButton->tRegion, dwColor);/* 居中写文字 */DrawTextInRegionCentral(strButton, &ptButton->tRegion, BUTTON_TEXT_COLOR);/* 刷新界面到 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);
}
四、根据输入事件找到按钮
对于触摸屏事件,根据iX、iY找到按钮.
对于网络数据,我们限定为这样的格式:“name ok”、“name err”、“name 70%”根据name找到按钮.
/* 判断点击的位置 */
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 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;
}
- 重写 main_page.c 的 Run 函数。
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);}
}
五、业务系统总流程测试
测试效果:
总结
这个电子量产工具的项目就到这里结束了,后面继续推出 面试笔试的 新专栏,帮助大家避开 笔试的坑。
【电子量产工具】6. 业务系统相关推荐
- 电子量产工具:输入系统-输入管理单元测试
软件总框图: 输入管理单元测试 添加input_test.c,内容如下 #include <sys/mman.h> #include <sys/types.h> #includ ...
- 【电子量产工具】4. UI系统
文章目录 前言 一.UI界面分析 二.结构体描述按钮 三.按钮初始化 四.默认绘制按键事件函数 五.默认按下按键事件函数 六.测试程序 实验效果 总结 前言 最近看了 电子量产工具 这个项目,本专栏是 ...
- 【电子量产工具】1.显示系统
文章目录 前言 一.显示系统分析 二.封装显示结构体 三.底层 Framebuffer 四.显示管理层 五.测试程序 实验效果图: 总结 前言 最近看了 电子量产工具 这个项目,本专栏是对该项目的一个 ...
- 电子产品量产工具-软件架构-显示系统
该笔记为百问网韦东山老师免费课程学习过程的整理,学习过程中,软件架构思想很重要,所以在每学习完一个单元后悔整理一下.由于韦老师在授课过程中的函数名称和变量命名时不太直观,所以我就自己根据软件分离来重新 ...
- 项目一:电子量产工具
软件总框架 1:设计构思-显示管理器 1.1 显示部分-数据结构抽象 对两个不同的设备(Frambuffer与WEB),抽象出同一个结构体类型, 总概括:先得到一个buffer,在这个buffer中你 ...
- 方便的U盘量产工具不刻盘装系统
2019独角兽企业重金招聘Python工程师标准>>> 可以把U盘模拟成usb-cdrom,iso文件弄到这个cdrom里面,在能usb启动的机器上设好usb-cdrom启动就可以利 ...
- 地平线:面向规模化量产的智能驾驶系统和软件开发
导读 7月27日,地平线在智东西公开课开设的「地平线自动驾驶技术专场」第3讲顺利完结,地平线智能驾驶应用软件部负责人宋巍围绕 <面向规模化量产的智能驾驶系统和软件开发>这一主题进行了直播讲 ...
- cruzer php sandisk 闪迪u盘量产工具_SanDisk Cruzer Micro下载
SanDisk Cruzer Micro电脑版是界面简洁而且使用很广泛的U盘量产工具,SanDisk Cruzer Micro最新版是一款闪存盘,数据传输率6MB/S,专注于U盘的分区.格 ...
- 天龙固件U盘更新_硅格T18D量产工具下载_硅格T18D量产工具官方版下载[u盘格式化]...
硅格T18D量产工具官方版是比较实用的u盘修复工具,硅格T18D量产工具官方版可以让使用者很轻松便捷的对硅格T18D进行量产操作,并支持修复和格式化的功能,提高U盘的性能,释放空间.硅格T ...
最新文章
- 广州网络推广是如何利用自媒体平台做好网络营销推广的?
- 如何在Apache环境下配置Rewrite规则
- CoreAnimation编程指南(九)图层布局
- Linux 进程间通信 - 信号量
- 中兴解禁后的第 52 天,我们可能摆脱美国科技产品吗?
- 10. CSS 文本
- 简单书籍类网页代码制作
- 教育培训机构拼团招生小程序公众号
- 冯诺依曼体系结构及三级缓存
- Material Design系列,自定义Behavior实现Android知乎首页
- 游戏设计模式——观察者模式(Observer)
- 停车场车牌识别收费系统厂家
- 枫叶蓝代码生成工具 和对服装行业的一些感悟
- Android单点触控技术,对图片进行平移,缩放,旋转操作
- 【公式小记】自相关、卷积、能量信号、功率信号
- Libvirt同步机制 —— 实现原理
- 还在羡慕微信/微博的图片处理?-android酷炫图片处理(下)
- VB.NET:控制阵列发生了什么
- U型地埋管(地埋管换热器采用单孔双U管)仿真教程
- 发布和共享 MATLAB 代码