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

news2024/10/6 7:12:32

前言

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

  • 量产工具一一显示系统(一)-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.coloradmin.cn/o/1895650.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

不到 5 元的随身 WiFi 刷 Debian 系统 做轻量家庭服务器

本文首发于只抄博客,欢迎点击原文链接了解更多内容。 前言 前不久在某宝均价 5 元买了两个随身 WiFi,拆机看了看丝印都是 MSM8916 ,正好是红米 2 同款的骁龙 410 的芯片,可以刷个 Debian 当作家庭服务器来跑一些轻量的服务。 不过手气不是很好,两个都是 512M + 4G 的配置…

快手矩阵系统源码:构建高效短视频生态的引擎

在短视频内容创作和管理领域&#xff0c;快手矩阵系统源码提供了一套全面的解决方案&#xff0c;帮助用户和企业高效地构建和管理自己的短视频平台。本文将深入探讨快手矩阵系统源码的核心功能&#xff0c;以及它如何助力用户在短视频领域取得成功。 快手矩阵系统源码概述 快…

【图书推荐】《HTML5+CSS3 Web前端开发与实例教程(微课视频版)》

本书用来干什么 详解HTML5、CSS3、Flex布局、Grid布局、AI技巧&#xff0c;通过两个网站设计案例提升Web前端开发技能&#xff0c;为读者深入学习Web前端开发打下牢固的基础。 配套资源非常齐全&#xff0c;可以当Web前端基础课的教材。 内容简介 本书秉承“思政引领&#…

后台管理系统日志管理模块的实现

一、日志管理系统 1.1目标效果图 1.2创建日志表&#xff0c;和对应的实体类 Data public class SysLog implements Serializable {private static final long serialVersionUID 1123526L;private Integer id;private String module;private String content;private Integer c…

Android C++系列:JNI中的Handler--ALooper

1. Android Handler回顾 在Android中,UI线程是一个很重要的概念。我们在日常开发中对UI的更新和一些系统行为,都必须在UI线程(主线程)中进行调用。我们在子线程更新UI时最常用的手段就是Handler,Handler的主要原理: 主要是有一个Looper不停的从队列读消息,子线程通过持有…

Redis-Redis可视化工具Redis Insight下载及安装

下载 1、博主已经上传资源&#xff0c;点此下载 2、点此进入官方下载 2.1 点击Installing Redis Insight 2.2 点击Install on desktop 2.3 选择Install on desktop&#xff0c;点击Redis Insight is available for download for free from this web site从网站下载 2.4 下载…

Anaconda+Pycharm两个软件从头到尾下载流程

前言&#xff1a; 1、使用教程前&#xff0c;请将电脑上的所有的Python卸载掉。再下载Anaconda&#xff0c;Anaconda这个软件里面就含有python。 彻底删除python方法&#xff1a; 1、计算机——属性——高级系统设置——环境变量 2、查看电脑用户自己设计的环境变量&#x…

FileZilla的安装和使用(快速上手版)

下载 登陆官网下载下载 - FileZilla中文网 服务端 我们选择一个中文安装最新版本下载 客户端 我们选择绿色免安装版进行下载 安装 安装服务端 双击运行下载好的服务端安装包 点击 我接受 点击 下一步 设置好安装路径&#xff0c;点击 下一步 这里默认即可&#xff0c;点击…

昇思25天学习打卡营第16天|文本解码原理——以MindNLP为例

在大模型中&#xff0c;文本解码通常是指在自然语言处理&#xff08;NLP&#xff09;任务中使用的大型神经网络模型&#xff08;如Transformer架构的模型&#xff09;将编码后的文本数据转换回可读的原始文本的过程。这些模型在处理自然语言时&#xff0c;首先将输入文本&#…

Understanding Zero Knowledge Proofs (ZKP)

Bilingual Tutorial: Understanding Zero Knowledge Proofs (ZKP) 双语教程&#xff1a;理解零知识证明&#xff08;ZKP&#xff09; Introduction 介绍 English: Zero Knowledge Proofs (ZKP) are a fascinating concept in cryptography where one party (the prover) can…

java项目自定义打印日志,打印请求方式,参数用时等

1.相关依赖 <!-- 私人工具包 --><dependency><groupId>cn.changeforyou</groupId><artifactId>location</artifactId><version>1.13-SNAPSHOT</version></dependency><!-- hutool工具依赖 --><dependency>…

六大Pixel新AI功能提升使用体验

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

探索如何赋予对象迭代魔法,轻松实现非传统解构赋值的艺术

前言 今天下午在网上冲浪过程中看到这样一个问题 面试题&#xff1a;如何让 var [a, b] {a: 1, b: 2} 解构赋值成功&#xff1f; 据说是某大厂面试题&#xff0c;于是我学习了一下这个问题&#xff0c;写下这篇文章记录一下。 学习过程 要想解决这个问题首先要知道什么是解…

nginx安装升级修复HTTP头信息泄露Nginx版本信息漏洞(并保持https配置)

文章目录 1. 准备工作2. 修改web服务器所使用的nginx的名称和版本信息2.1 修改以下三个文件&#xff1a;(1) src/core目录下的nginx.h文件(2) src/http目录下的ngx_http_header_filter_module.c文件(3) src/http目录下的ngx_http_special_response.c文件 2.2 重新编译nginx2.3 …

Spring框架的学习前言

1.注意事项 1.在接下来的学习中我们会将jdk的版本升级到17。 2.引入maven仓库用来存储依赖 3.在后面的javaSpring框架中要第一个项目的创建要选javaweb和lombook这两个依赖 2.Maven的主要功能 &#xff08;1&#xff09;maven的主要功能是引入依赖和管理依赖&#xff0c;在…

第7章:Electron文件系统操作(2)

7.2 文件对话框 Electron 提供了 dialog 模块用于显示文件打开和保存对话框。 7.2.1 显示文件打开对话框 主进程代码&#xff1a; const { app, BrowserWindow, ipcMain, dialog } require(electron); const path require(path);let mainWindow;const createMainWindow …

【Ubuntu】详细说说Parallels DeskTop安装和使用Ubuntu系统

希望文章能给到你启发和灵感~ 如果觉得文章对你有帮助的话,点赞 + 关注+ 收藏 支持一下博主吧~ 阅读指南 开篇说明一、基础环境说明1.1 硬件环境1.2 软件环境二、Ubuntu系统的使用2.1 系统的下载2.2 系统的安装2.3 安装桌面版(可选)2.3.1 安装/更新apt2.3.2 安装桌面版2.3…

4.通过制作trackbar控件了解3原色在opencv的应用-cnblog

通过制作trackbar控件了解3原色在opencv的应用 什么是3原色 一张彩色图片通常是由三种基本颜色&#xff0c;即红色、绿色和蓝色&#xff08;通常称为RGB&#xff09;的混合组成的。这三种颜色以不同的比例混合可以产生几乎所有其他颜色。在数字图像中&#xff0c;每个像素通常…

找不到msvcr110.dll是怎么回事?彻底解决msvcr110.dll丢失的方法

当您的电脑提示遇到msvcr110.dll丢失时&#xff0c;您知道如何解决此问题吗&#xff1f;事实上&#xff0c;解决此类dll文件丢失的问题相对较为简单。只要我们深入了解msvcr110.dll丢失的具体情况&#xff0c;便可轻松解决此问题。以下为您介绍msvcr110.dll修复方法。 一&#…