【电子量产工具】4. UI系统

前言

最近看了 电子量产工具 这个项目,本专栏是对该项目的一个总结。


一、UI界面分析

在这里插入图片描述

UI用户界面(User Interface)的缩写,指的是人与计算机或其他设备进行交互时所使用的界面。用户界面是用户与系统之间的桥梁,提供了一种方式让用户与计算机进行沟通、操作和获取信息。
用户界面可以包括以下几个方面:

  • 图形用户界面(GUI)。
  • 命令行界面(CLI)
  • 触摸界面
  • 声音界面
  • 虚拟现实界面(VR)和增强现实界面(AR)

我们的UI系统,就是构造各类GUI元素,比如按钮(目前只实现按钮)。

二、结构体描述按钮

/* 函数指针(绘制按键) */
typedef int (*ONDRAW_FUNC)(struct Button *ptButton, PDispBuff ptDispBuff);
/* 函数指针(按下按钮) */
typedef int (*ONPRESSED_FUNC)(struct Button *ptButton, PDispBuff ptDispBuff, PInputEvent ptInputEvent);


typedef struct Button {
	char *name;								// 按键 名字
	int status;								//按键 按下状态
	Region tRegion;							// 按键的区域
	ONDRAW_FUNC OnDraw;						//一个 ONDRAW_FUNC 类型的函数指针,用于指向按钮绘制函数
	ONPRESSED_FUNC OnPressed;				//一个 ONPRESSED_FUNC 类型的函数指针,用于指向按钮按下事件处理函数
}Button, *PButton;
typedef struct Region {				//区域包括 左上角坐标, 高, 宽
	int iLeftUpX;
	int iLeftUpY;
	int iWidth;
	int iHeigh;
}Region, *PRegion;

三、按钮初始化

void InitButton(PButton ptButton, char *name, PRegion ptRegion, ONDRAW_FUNC OnDraw, ONPRESSED_FUNC OnPressed)
{
	ptButton->status = 0;				//初始状态为 0 ,未按下
	ptButton->name = name;
	ptButton->tRegion = *ptRegion;			// 按钮的区域
	ptButton->OnDraw    = OnDraw ? OnDraw : DefaultOnDraw;		//若 OnDraw 为空,则执行默认绘制函数DefaultOnDraw
	ptButton->OnPressed = OnPressed ? OnPressed : DefaultOnPressed;	 //若 OnPressed 为空,则执行默认绘制函数DefaultOnPressed
}

四、默认绘制按键事件函数

绘制各个按钮 Button 的底色,文字,并将其刷新到 DispBuff 上

static int DefaultOnDraw(struct Button *ptButton, PDispBuff ptDispBuff)
{
	/* 绘制底色 */
	DrawRegion(&ptButton->tRegion, BUTTON_DEFAULT_COLOR);		// 红色 0xff0000

	/* 居中写文字 */
	DrawTextInRegionCentral(ptButton->name, &ptButton->tRegion, BUTTON_TEXT_COLOR);		//黑色 0x000000

	/* flush to lcd/web */
	FlushDisplayRegion(&ptButton->tRegion, ptDispBuff);

	return 0;
}
  1. 绘制底色
void DrawRegion(PRegion ptRegion, unsigned int dwColor)
{
	int x = ptRegion->iLeftUpX;
	int y = ptRegion->iLeftUpY;
	int width = ptRegion->iWidth;
	int heigh = ptRegion->iHeigh;

	int i,j;

	for (j = y; j < y + heigh; j++)
	{
		for (i = x; i < x + width; i++)
			PutPixel(i, j, dwColor);			//描点函数
	}
}
  1. 居中写文字
    在 一定的区域 Region,按颜色 dwColor 居中显示名字 name
void DrawTextInRegionCentral(char *name, PRegion ptRegion, unsigned int dwColor)
{
	int n = strlen(name);
	int iFontSize = ptRegion->iWidth / n / 2;
	FontBitMap tFontBitMap;

	int iOriginX, iOriginY;
	int i = 0;
	int error;

	if (iFontSize > ptRegion->iHeigh)				//计算字体大小
		iFontSize =  ptRegion->iHeigh;
		
	/* 当前文字的基点 */
	iOriginX = (ptRegion->iWidth - n * iFontSize)/2 + ptRegion->iLeftUpX;
	iOriginY = (ptRegion->iHeigh - iFontSize)/2 + iFontSize + ptRegion->iLeftUpY;

	SetFontSize(iFontSize);					// 设置字体大小

	while (name[i])			//字符编码
	{
		/* get bitmap */
		tFontBitMap.iCurOriginX = iOriginX;
		tFontBitMap.iCurOriginY = iOriginY;
		error = GetFontBitMap(name[i], &tFontBitMap);		//根据字符编码获取位图,保存在 参数 tFontBitMap中
		if (error)
		{
			printf("SelectAndInitFont err\n");
			return;
		}

		/* draw on buffer */		
		DrawFontBitMap(&tFontBitMap, dwColor);			// 绘制位图	

		iOriginX = tFontBitMap.iNextOriginX;			//获取下一文字的基点坐标
		iOriginY = tFontBitMap.iNextOriginY;	
		i++;
	}
}
  1. 将绘制到的按钮,刷新到 buffer 上。

返回 LCDframebuffer , 以后上层 APP 可以直接操作LCD, 可以不用 FbFlushRegion
也可以 malloc 返回一块无关的buffer, 要使用 FbFlushRegion

这里 为了 以后代码的可移植性,加上了刷新界面,但 并未做出任何举动。

在这里插入图片描述

五、默认按下按键事件函数

按下按键事件函数 也需要 上面 绘制函数 里的 : 绘制底色, 居中写文字 ,刷新界面。这里就不再 重述了。

static int DefaultOnPressed(struct Button *ptButton, PDispBuff ptDispBuff, PInputEvent ptInputEvent)
{
	unsigned int dwColor = BUTTON_DEFAULT_COLOR;		//按钮初始颜色 红色,0xff0000
	
	ptButton->status = !ptButton->status;				// 按钮状态,未按下时 为 0 
	if (ptButton->status)
		dwColor = BUTTON_PRESSED_COLOR;					//按下的颜色为 绿色, 0x00ff00

	/* 绘制底色 */
	DrawRegion(&ptButton->tRegion, dwColor);

	/* 居中写文字 */
	DrawTextInRegionCentral(ptButton->name, &ptButton->tRegion, BUTTON_TEXT_COLOR);

	/* 刷新界面 到 lcd/web */
	FlushDisplayRegion(&ptButton->tRegion, ptDispBuff);
	return 0;
}

六、测试程序

  1. 显示界面初始化
    在这里插入图片描述
  2. 字体初始化
    在这里插入图片描述
  3. ui 界面
	/* 设置按钮的显示位置,宽高 */
	tRegion.iLeftUpX = 200;
	tRegion.iLeftUpY = 200;
	tRegion.iWidth   = 300;
	tRegion.iHeigh   = 100;
	
	/* 显示 "test", 调用默认绘制,按下函数 */
	InitButton(&tButton, "test", &tRegion, NULL, NULL);
	tButton.OnDraw(&tButton, ptBuffer);				//绘制按键
	while (1)
	{
		tButton.OnPressed(&tButton, ptBuffer, NULL);	//按下按键,
		sleep(2);		// 休眠 2 秒
	}

实验效果

实验结果就是每隔 2 秒,自动 变换按键的颜色。(我按钮后面的图是 自己的QT界面,忽略即可)
在这里插入图片描述
在这里插入图片描述


总结

UI 系统界面的逻辑性 不难,就是一些函数的编写有些困难。
这些封装好的代码,可以用于以后代码的一直调用。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

糖果罐子♡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值