量产工具一一UI系统(四)

news/2024/7/8 16:16:24 标签: IMX6ULL, linux

前言

前面我们实现了显示系统框架,输入系统框架和文字系统框架,链接:

  • 量产工具一一显示系统(一)-CSDN博客
  • 量产工具一一输入系统(二)-CSDN博客
  • 量产工具一一文字系统(三)-CSDN博客

接下来我们来实现UI系统框架。

一、按钮数据结构抽象

1.所谓UI,就是User Interface(用户界面),有图像界面(GUI)等。

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

3.怎么描述一个按钮呢?

  • 它的位置、大小怎么表示?
  • 怎么绘制它?
  • 用户点击它之后,如何处理?

1.ui.h

#ifndef _UI_H
#define _UI_H

#include <common.h>
#include <disp_manager.h>
#include <input_manager.h>

/* 定义按钮的默认颜色、按下时的颜色和文本颜色 */
#define BUTTON_DEFAULT_COLOR 0xff0000 // 默认颜色,设置为红色
#define BUTTON_PRESSED_COLOR 0x00ff00 // 按下时的颜色,设置为绿色
#define BUTTON_PERCENT_COLOR 0x0000ff // 百分比颜色,设置为蓝色
#define BUTTON_TEXT_COLOR    0x000000 // 文本颜色,设置为黑色

struct Button;

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 iFontSize;
	int status;
	Region tRegion;
	ONDRAW_FUNC OnDraw;
	ONPRESSED_FUNC OnPressed;
}Button, *PButton;

void InitButton(PButton ptButton, char *name, PRegion ptRegion, ONDRAW_FUNC OnDraw, ONPRESSED_FUNC OnPressed);

#endif

二、按键处理

1.点击按钮后怎么处理,是业务系统的事情

2.所以应该提供一个InitButton函数,让用户可以提供OnPressed函数

3.上层代码通过下面3个函数使用按钮

1.button.c

  • 绘制按钮:通过DefaultOnDraw函数,按钮在未按下时显示默认颜色和文本。
  • 响应按钮按下:通过DefaultOnPressed函数处理按钮的按下事件,改变按钮的状态和颜色。
  • 初始化按钮:通过InitButton函数用于初始化按钮的各项属性,包括名称、区域、绘制函数和按下处理函数。 
#include <ui.h>

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

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

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

	return 0;
}

static int DefaultOnPressed(struct Button *ptButton, PDispBuff ptDispBuff, PInputEvent ptInputEvent)
{
	unsigned int dwColor = BUTTON_DEFAULT_COLOR;
	
	ptButton->status = !ptButton->status;
	if (ptButton->status)
		dwColor = BUTTON_PRESSED_COLOR;

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

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

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

void InitButton(PButton ptButton, char *name, PRegion ptRegion, ONDRAW_FUNC OnDraw, ONPRESSED_FUNC OnPressed)
{
	ptButton->status = 0;
	ptButton->name = name;
	if (ptRegion)
		ptButton->tRegion = *ptRegion;
	ptButton->OnDraw    = OnDraw ? OnDraw : DefaultOnDraw;
	ptButton->OnPressed = OnPressed ? OnPressed : DefaultOnPressed;
}

2.disp_manager.c

新增函数  void DrawRegion(PRegion ptRegion, unsigned int dwColor) 用于绘制一个指定颜色和区域的矩形。

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);
	}
}

 在一个区域ptRegion中间将位置居中,并且设置字体颜色

新增函数  void DrawTextInRegionCentral(char *name, PRegion ptRegion, unsigned int dwColor),将位置区域居中。

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);
		if (error)
		{
			printf("SelectAndInitFont err\n");
			return;
		}

		/* draw on buffer */		
		DrawFontBitMap(&tFontBitMap, dwColor);		

		/* 更新下一个字符的起始坐标 */
		iOriginX = tFontBitMap.iNextOriginX;
		iOriginY = tFontBitMap.iNextOriginY;	
		i++;
	}
	
}

3.disp_manager.h

#ifndef _DISP_MANAGER_H
#define _DISP_MANAGER_H
 
#include <common.h>
#include <font_manager.h>

typedef struct DispBuff {
	int iXres;
	int iYres;
	int iBpp;
	char *buff;
}DispBuff, *PDispBuff;


typedef struct DispOpr {
	char *name;
	int (*DeviceInit)(void);
	int (*DeviceExit)(void);
	int (*GetBuffer)(PDispBuff ptPDispBuff);
	int (*FlushRegion)(PRegion ptRegion, PDispBuff ptPDispBuff);
	struct DispOpr *ptNext;
}DispOpr, *PDispOpr;

int PutPixel(int x, int y, unsigned int dwColor);
void RegisterDisplay(PDispOpr ptPDispOpr);
int SelectDefaultDisplay(char *name);
int InitDefaultDisplay(void);
PDispBuff GetDisplayBuffer(void);
int FlushDisplayRegion(PRegion ptPRegion, PDispBuff ptPDispBuff);
void DisplaySystemRegister(void);
void DrawFontBitMap(PFontBitMap ptFontBitMap, unsigned int dwColor);
void DrawRegion(PRegion ptRegion, unsigned int dwColor);
void DrawTextInRegionCentral(char *name, PRegion ptRegion, unsigned int dwColor);


#endif

三、单元测试

1.ui_test.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 <ui.h>

int main(int argc, char **argv)
{
	PDispBuff ptBuffer;
	int error;
	Button tButton;
	Region tRegion;

	if (argc != 2)
	{
		printf("Usage: %s <font_size>\n", argv[0]);
		return -1;
	}
	/* FB Init*/
	DisplaySystemRegister();

	SelectDefaultDisplay("fb");

	InitDefaultDisplay();

	ptBuffer = GetDisplayBuffer();
	
	/* Font Init*/
	FontSystemRegister();
	
	error = SelectAndInitFont("freetype", argv[1]);
	if (error)
	{
		printf("SelectAndInitFont err\n");
		return -1;
	}

	tRegion.iLeftUpX = 200;
	tRegion.iLeftUpY = 200;
	tRegion.iWidth   = 300;
	tRegion.iHeigh   = 100;
	
	InitButton(&tButton, "test", &tRegion, NULL, NULL);
	tButton.OnDraw(&tButton, ptBuffer);
	while (1)
	{
		tButton.OnPressed(&tButton, ptBuffer, NULL);
		sleep(2);
	}
	
	return 0;	
}

2.上机测试

上电开发板,挂载 Ubuntu 的 NFS 目录,编译测试:


http://www.niftyadmin.cn/n/5537381.html

相关文章

汽车免拆诊断案例 | 2021款路虎揽胜运动版车遥控及一键起动功能失效

故障现象 一辆2021款路虎揽胜运动版车&#xff0c;搭载AJ20-P6H3L发动机&#xff0c;累计行驶里程约为2.5万km。车主反映&#xff0c;使用智能钥匙无法解锁车门&#xff0c;使用机械钥匙打开车门&#xff0c;进入车内&#xff0c;发现一键起动功能也失效&#xff1b;根据组合…

206. 反转链表 (Swift 版本)

题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 解题 /*** Definition for singly-linked list.* public class ListNode {* public var val: Int* public var next: ListNode?* public init() { self.val 0; self.…

云计算【第一阶段(23)】Linux系统安全及应用

一、账号安全控制 1.1、账号安全基本措施 1.1.1、系统账号清理 将非登录用户的shell设为/sbin/nologin锁定长期不使用的账号删除无用的账号 1.1.1.1、实验1 用于匹配以/sbin/nologin结尾的字符串&#xff0c;$ 表示行的末尾。 &#xff08;一般是程序用户改为nologin&…

深度学习笔记: 最详尽解释预测系统的分类指标(精确率、召回率和 F1 值)

欢迎收藏Star我的Machine Learning Blog:https://github.com/purepisces/Wenqing-Machine_Learning_Blog。如果收藏star, 有问题可以随时与我交流, 谢谢大家&#xff01; 预测系统的分类指标(精确率、召回率和 F1 值) 简介 让我们来谈谈预测系统的分类指标以及对精确率、召回…

高效前端开发:解密pnpm的存储与链接

什么是pnpm PNPM&#xff08;Performant NPM&#xff09;是一种快速且节省磁盘空间的包管理工具。相较于其他包管理器如NPM和Yarn&#xff0c;PNPM通过独特的存储机制和链接技术解决了许多常见的问题。以下是PNPM如何避免这些问题以及其关键技术的详细介绍。 特性 PNPM Store…

手动将dingtalk-sdk-java jar包打入maven本地仓库

有时候,中央镜像库不一定有自己需要的jar包,这时候我们就需要用到该方法,将jar打入maven本地仓库,然后项目中,正常使用maven的引入规则。 mvn install:install-file -Dmaven.repo.local=D:\software\maven\apache-maven-3.6.3-bin\apache-maven-3.6.3\repo -DgroupId=ding…

VSCode中使用CMake管理

使用 CMake 配置 Visual Studio Code (VSCode) 项目是许多 C 开发者的常见需求。下面我将详细介绍在 VSCode 中使用 CMake 的步骤和最佳实践。 前提条件 安装 VSCode&#xff1a;如果还未安装&#xff0c;请先前往 VSCode 下载页面下载安装。 CMake&#xff1a;安装 CMake 工…

【Android源码】Gerrit上传Android源码

关于Gerrit的安装参考下面链接 【Android源码】Gerrit安装 要实现上传Android源码&#xff0c;需要经历以下几步&#xff1a; 下载Android代码创建源码仓库创建manifests仓库上传源码其他电脑下载源码 要证明Gerrit中的源码真实可用&#xff0c;肯定是以其他人能真正共享到代…